lib/ctf-ir/event.c: logging: remove some context given by other statement
[babeltrace.git] / lib / 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>
ac0c6bdd
PP
30#include <babeltrace/ctf-writer/clock-internal.h>
31#include <babeltrace/ctf-ir/clock-class-internal.h>
11b0cdc8 32#include <babeltrace/ctf-writer/event.h>
272df73e 33#include <babeltrace/ctf-ir/event-class-internal.h>
11b0cdc8 34#include <babeltrace/ctf-ir/event-internal.h>
2e33ac5a
PP
35#include <babeltrace/ctf-ir/field-types-internal.h>
36#include <babeltrace/ctf-ir/fields-internal.h>
11b0cdc8
JG
37#include <babeltrace/ctf-writer/stream.h>
38#include <babeltrace/ctf-ir/stream-class-internal.h>
09840de5 39#include <babeltrace/ctf-ir/validation-internal.h>
8bf65fbd 40#include <babeltrace/ctf-ir/visitor-internal.h>
11b0cdc8 41#include <babeltrace/ctf-writer/functor-internal.h>
654c1444 42#include <babeltrace/ctf-ir/utils.h>
83509119 43#include <babeltrace/ref.h>
3d9990ac
PP
44#include <babeltrace/compiler-internal.h>
45#include <babeltrace/align-internal.h>
46#include <babeltrace/endian-internal.h>
dc3fffef 47#include <inttypes.h>
544d0515 48#include <stdint.h>
11b0cdc8
JG
49
50static
83509119 51void bt_ctf_stream_class_destroy(struct bt_object *obj);
11b0cdc8 52static
662e778c 53int init_event_header(struct bt_ctf_stream_class *stream_class);
11b0cdc8 54static
662e778c 55int init_packet_context(struct bt_ctf_stream_class *stream_class);
11b0cdc8
JG
56
57struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
58{
e0e2946b
PP
59 struct bt_ctf_stream_class *stream_class =
60 bt_ctf_stream_class_create_empty(name);
12c8a1a3 61 int ret;
e0e2946b
PP
62
63 if (!stream_class) {
64 goto error;
65 }
66
67 ret = init_event_header(stream_class);
68 if (ret) {
69 goto error;
70 }
71
72 ret = init_packet_context(stream_class);
73 if (ret) {
74 goto error;
75 }
76
77 return stream_class;
78
79error:
80 BT_PUT(stream_class);
81 return stream_class;
82}
83
84struct bt_ctf_stream_class *bt_ctf_stream_class_create_empty(const char *name)
85{
11b0cdc8
JG
86 struct bt_ctf_stream_class *stream_class = NULL;
87
3ea33115 88 if (name && bt_ctf_validate_identifier(name)) {
11b0cdc8
JG
89 goto error;
90 }
91
92 stream_class = g_new0(struct bt_ctf_stream_class, 1);
93 if (!stream_class) {
94 goto error;
95 }
96
97 stream_class->name = g_string_new(name);
98 stream_class->event_classes = g_ptr_array_new_with_free_func(
e6a8e8e4 99 (GDestroyNotify) bt_object_release);
11b0cdc8 100 if (!stream_class->event_classes) {
83509119 101 goto error;
11b0cdc8
JG
102 }
103
0b9ce69f
JG
104 stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
105 g_int64_equal, g_free, NULL);
106
e0e2946b
PP
107 stream_class->packet_context_type = bt_ctf_field_type_structure_create();
108 if (!stream_class->packet_context_type) {
83509119 109 goto error;
662e778c
JG
110 }
111
e0e2946b
PP
112 stream_class->event_header_type = bt_ctf_field_type_structure_create();
113 if (!stream_class->event_header_type) {
114 goto error;
115 }
116
117 stream_class->event_context_type = bt_ctf_field_type_structure_create();
118 if (!stream_class->event_context_type) {
83509119 119 goto error;
12c8a1a3
JG
120 }
121
83509119 122 bt_object_init(stream_class, bt_ctf_stream_class_destroy);
11b0cdc8
JG
123 return stream_class;
124
11b0cdc8 125error:
e0e2946b 126 BT_PUT(stream_class);
11b0cdc8
JG
127 return stream_class;
128}
129
142c5610
JG
130struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
131 struct bt_ctf_stream_class *stream_class)
132{
dc3fffef
PP
133 return stream_class ?
134 bt_get(bt_ctf_stream_class_borrow_trace(stream_class)) :
135 NULL;
142c5610
JG
136}
137
69dc4535
JG
138const char *bt_ctf_stream_class_get_name(
139 struct bt_ctf_stream_class *stream_class)
140{
141 const char *name = NULL;
142
143 if (!stream_class) {
144 goto end;
145 }
146
147 name = stream_class->name->str;
148end:
149 return name;
150}
151
3ea33115
JG
152int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
153 const char *name)
154{
155 int ret = 0;
156
157 if (!stream_class || stream_class->frozen) {
158 ret = -1;
159 goto end;
160 }
161
162 g_string_assign(stream_class->name, name);
163end:
164 return ret;
165}
166
2f100782
JG
167struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
168 struct bt_ctf_stream_class *stream_class)
169{
170 struct bt_ctf_clock *clock = NULL;
171
172 if (!stream_class || !stream_class->clock) {
173 goto end;
174 }
175
ac0c6bdd 176 clock = bt_get(stream_class->clock);
2f100782
JG
177end:
178 return clock;
179}
180
11b0cdc8
JG
181int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
182 struct bt_ctf_clock *clock)
183{
184 int ret = 0;
eee752e5 185 struct bt_ctf_field_type *timestamp_field = NULL;
11b0cdc8 186
ac0c6bdd 187 if (!stream_class || !clock || stream_class->frozen) {
11b0cdc8
JG
188 ret = -1;
189 goto end;
190 }
191
eee752e5 192 /*
ac0c6bdd
PP
193 * Look for a "timestamp" integer field type in the stream
194 * class's event header field type and map the stream class's
195 * clock's class to that field type if there's no current
196 * mapping.
eee752e5
JG
197 */
198 timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
199 stream_class->event_header_type, "timestamp");
200 if (timestamp_field) {
ac0c6bdd
PP
201 struct bt_ctf_clock_class *mapped_clock_class =
202 bt_ctf_field_type_integer_get_mapped_clock_class(
203 timestamp_field);
204
205 if (!mapped_clock_class) {
206 ret = bt_ctf_field_type_integer_set_mapped_clock_class(
207 timestamp_field, clock->clock_class);
208 if (ret) {
209 goto end;
210 }
eee752e5
JG
211 }
212
ac0c6bdd 213 BT_PUT(mapped_clock_class);
eee752e5
JG
214 }
215
ac0c6bdd
PP
216 /* Replace the current clock of this stream class. */
217 bt_put(stream_class->clock);
218 stream_class->clock = bt_get(clock);
11b0cdc8 219
11b0cdc8 220end:
ac0c6bdd 221 bt_put(timestamp_field);
11b0cdc8
JG
222 return ret;
223}
224
2f100782
JG
225int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
226{
227 int64_t ret;
228
229 if (!stream_class || !stream_class->id_set) {
9ac68eb1 230 ret = (int64_t) -1;
2f100782
JG
231 goto end;
232 }
233
9ac68eb1 234 ret = stream_class->id;
2f100782
JG
235end:
236 return ret;
237}
238
5ca83563
JG
239BT_HIDDEN
240int _bt_ctf_stream_class_set_id(
9ac68eb1 241 struct bt_ctf_stream_class *stream_class, int64_t id)
5ca83563
JG
242{
243 stream_class->id = id;
244 stream_class->id_set = 1;
245 return 0;
246}
247
9ac68eb1
PP
248struct event_class_set_stream_class_id_data {
249 int64_t stream_class_id;
29664b2a
PP
250 int ret;
251};
252
253static
254void event_class_set_stream_id(gpointer event_class, gpointer data)
255{
9ac68eb1 256 struct event_class_set_stream_class_id_data *typed_data = data;
29664b2a
PP
257
258 typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
9ac68eb1 259 typed_data->stream_class_id);
29664b2a
PP
260}
261
262BT_HIDDEN
263int bt_ctf_stream_class_set_id_no_check(
9ac68eb1 264 struct bt_ctf_stream_class *stream_class, int64_t id)
2f100782
JG
265{
266 int ret = 0;
9ac68eb1
PP
267 struct event_class_set_stream_class_id_data data =
268 { .stream_class_id = id, .ret = 0 };
2f100782 269
29664b2a
PP
270 /*
271 * Make sure all event classes have their "stream_id" attribute
272 * set to this value.
273 */
274 g_ptr_array_foreach(stream_class->event_classes,
275 event_class_set_stream_id, &data);
276 ret = data.ret;
277 if (ret) {
2f100782
JG
278 goto end;
279 }
280
5ca83563
JG
281 ret = _bt_ctf_stream_class_set_id(stream_class, id);
282 if (ret) {
283 goto end;
284 }
2f100782
JG
285end:
286 return ret;
287}
288
29664b2a 289int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
9ac68eb1 290 uint64_t id_param)
29664b2a
PP
291{
292 int ret = 0;
9ac68eb1 293 int64_t id = (int64_t) id_param;
29664b2a 294
9ac68eb1 295 if (!stream_class || stream_class->frozen || id < 0) {
29664b2a
PP
296 ret = -1;
297 goto end;
298 }
299
300 ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
301end:
302 return ret;
303}
304
0d23acbe
PP
305static
306void event_class_exists(gpointer element, gpointer query)
307{
308 struct bt_ctf_event_class *event_class_a = element;
309 struct search_query *search_query = query;
310 struct bt_ctf_event_class *event_class_b = search_query->value;
311 int64_t id_a, id_b;
312
313 if (search_query->value == element) {
314 search_query->found = 1;
315 goto end;
316 }
317
0d23acbe
PP
318 /*
319 * Two event classes cannot share the same ID in a given
320 * stream class.
321 */
322 id_a = bt_ctf_event_class_get_id(event_class_a);
323 id_b = bt_ctf_event_class_get_id(event_class_b);
324
325 if (id_a < 0 || id_b < 0) {
326 /* at least one ID is not set: will be automatically set later */
327 goto end;
328 }
329
330 if (id_a == id_b) {
331 search_query->found = 1;
332 goto end;
333 }
334
335end:
336 return;
337}
338
11b0cdc8
JG
339int bt_ctf_stream_class_add_event_class(
340 struct bt_ctf_stream_class *stream_class,
341 struct bt_ctf_event_class *event_class)
342{
343 int ret = 0;
0b9ce69f 344 int64_t *event_id = NULL;
e6a8e8e4
JG
345 struct bt_ctf_trace *trace = NULL;
346 struct bt_ctf_stream_class *old_stream_class = NULL;
09840de5
PP
347 struct bt_ctf_validation_output validation_output = { 0 };
348 struct bt_ctf_field_type *packet_header_type = NULL;
349 struct bt_ctf_field_type *packet_context_type = NULL;
350 struct bt_ctf_field_type *event_header_type = NULL;
351 struct bt_ctf_field_type *stream_event_ctx_type = NULL;
352 struct bt_ctf_field_type *event_context_type = NULL;
353 struct bt_ctf_field_type *event_payload_type = NULL;
354 const enum bt_ctf_validation_flag validation_flags =
355 BT_CTF_VALIDATION_FLAG_EVENT;
11b0cdc8
JG
356
357 if (!stream_class || !event_class) {
358 ret = -1;
359 goto end;
360 }
361
5acf2ae6
PP
362 trace = bt_ctf_stream_class_get_trace(stream_class);
363 if (trace && trace->is_static) {
364 ret = -1;
365 goto end;
366 }
367
0b9ce69f
JG
368 event_id = g_new(int64_t, 1);
369 if (!event_id) {
370 ret = -1;
371 goto end;
372 }
373
11b0cdc8
JG
374 /* Check for duplicate event classes */
375 struct search_query query = { .value = event_class, .found = 0 };
0d23acbe
PP
376 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
377 &query);
11b0cdc8
JG
378 if (query.found) {
379 ret = -1;
380 goto end;
381 }
382
09840de5 383 old_stream_class = bt_ctf_event_class_get_stream_class(event_class);
e6a8e8e4
JG
384 if (old_stream_class) {
385 /* Event class is already associated to a stream class. */
386 ret = -1;
387 goto end;
388 }
389
e6a8e8e4 390 if (trace) {
09840de5
PP
391 /*
392 * If the stream class is associated with a trace, then
393 * both those objects are frozen. Also, this event class
394 * is about to be frozen.
395 *
396 * Therefore the event class must be validated here.
397 * The trace and stream class should be valid at this
398 * point.
399 */
400 assert(trace->valid);
401 assert(stream_class->valid);
402 packet_header_type =
403 bt_ctf_trace_get_packet_header_type(trace);
404 packet_context_type =
405 bt_ctf_stream_class_get_packet_context_type(
406 stream_class);
407 event_header_type =
408 bt_ctf_stream_class_get_event_header_type(stream_class);
409 stream_event_ctx_type =
410 bt_ctf_stream_class_get_event_context_type(
411 stream_class);
412 event_context_type =
413 bt_ctf_event_class_get_context_type(event_class);
414 event_payload_type =
415 bt_ctf_event_class_get_payload_type(event_class);
416 ret = bt_ctf_validate_class_types(
417 trace->environment, packet_header_type,
418 packet_context_type, event_header_type,
419 stream_event_ctx_type, event_context_type,
420 event_payload_type, trace->valid,
421 stream_class->valid, event_class->valid,
422 &validation_output, validation_flags);
423 BT_PUT(packet_header_type);
424 BT_PUT(packet_context_type);
425 BT_PUT(event_header_type);
426 BT_PUT(stream_event_ctx_type);
427 BT_PUT(event_context_type);
428 BT_PUT(event_payload_type);
429
26079216 430 if (ret) {
09840de5
PP
431 /*
432 * This means something went wrong during the
433 * validation process, not that the objects are
434 * invalid.
435 */
436 goto end;
437 }
438
439 if ((validation_output.valid_flags & validation_flags) !=
440 validation_flags) {
441 /* Invalid event class */
442 ret = -1;
26079216
JG
443 goto end;
444 }
445 }
446
09840de5 447 /* Only set an event ID if none was explicitly set before */
0b9ce69f 448 *event_id = bt_ctf_event_class_get_id(event_class);
24626e8b 449 if (*event_id < 0) {
2f100782
JG
450 if (bt_ctf_event_class_set_id(event_class,
451 stream_class->next_event_id++)) {
452 ret = -1;
453 goto end;
454 }
0b9ce69f 455 *event_id = stream_class->next_event_id;
2f100782
JG
456 }
457
29664b2a
PP
458 ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
459 if (ret) {
460 goto end;
461 }
462
e6a8e8e4 463 bt_object_set_parent(event_class, stream_class);
09840de5
PP
464
465 if (trace) {
466 /*
467 * At this point we know that the function will be
468 * successful. Therefore we can replace the event
469 * class's field types with what's in the validation
470 * output structure and mark this event class as valid.
471 */
472 bt_ctf_validation_replace_types(NULL, NULL, event_class,
473 &validation_output, validation_flags);
474 event_class->valid = 1;
475
476 /*
477 * Put what was not moved in
478 * bt_ctf_validation_replace_types().
479 */
480 bt_ctf_validation_output_put_types(&validation_output);
481 }
482
483 /* Add to the event classes of the stream class */
11b0cdc8 484 g_ptr_array_add(stream_class->event_classes, event_class);
0b9ce69f
JG
485 g_hash_table_insert(stream_class->event_classes_ht, event_id,
486 event_class);
487 event_id = NULL;
09840de5
PP
488
489 /* Freeze the event class */
58203827 490 bt_ctf_event_class_freeze(event_class);
5ca83563 491
9b888ff3
JG
492 /* Notifiy listeners of the trace's schema modification. */
493 if (trace) {
d9a13d86
PP
494 struct bt_ctf_object obj = { .object = event_class,
495 .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
9b888ff3 496
d9a13d86 497 (void) bt_ctf_trace_object_modification(&obj, trace);
9b888ff3 498 }
11b0cdc8 499end:
e6a8e8e4
JG
500 BT_PUT(trace);
501 BT_PUT(old_stream_class);
09840de5
PP
502 bt_ctf_validation_output_put_types(&validation_output);
503 assert(!packet_header_type);
504 assert(!packet_context_type);
505 assert(!event_header_type);
506 assert(!stream_event_ctx_type);
507 assert(!event_context_type);
508 assert(!event_payload_type);
0b9ce69f 509 g_free(event_id);
09840de5 510
11b0cdc8
JG
511 return ret;
512}
513
544d0515 514int64_t bt_ctf_stream_class_get_event_class_count(
69dc4535
JG
515 struct bt_ctf_stream_class *stream_class)
516{
544d0515 517 int64_t ret;
69dc4535
JG
518
519 if (!stream_class) {
9ac68eb1 520 ret = (int64_t) -1;
69dc4535
JG
521 goto end;
522 }
523
9ac68eb1 524 ret = (int64_t) stream_class->event_classes->len;
69dc4535
JG
525end:
526 return ret;
527}
528
9ac68eb1
PP
529struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_index(
530 struct bt_ctf_stream_class *stream_class, uint64_t index)
69dc4535
JG
531{
532 struct bt_ctf_event_class *event_class = NULL;
533
9ac68eb1 534 if (!stream_class || index >= stream_class->event_classes->len) {
69dc4535
JG
535 goto end;
536 }
537
538 event_class = g_ptr_array_index(stream_class->event_classes, index);
83509119 539 bt_get(event_class);
69dc4535
JG
540end:
541 return event_class;
542}
543
0863f950 544struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
9ac68eb1 545 struct bt_ctf_stream_class *stream_class, uint64_t id)
0863f950 546{
9ac68eb1 547 int64_t id_key = (int64_t) id;
0863f950
PP
548 struct bt_ctf_event_class *event_class = NULL;
549
9ac68eb1 550 if (!stream_class || id_key < 0) {
0863f950
PP
551 goto end;
552 }
553
0b9ce69f
JG
554 event_class = g_hash_table_lookup(stream_class->event_classes_ht,
555 &id_key);
556 bt_get(event_class);
0863f950
PP
557end:
558 return event_class;
559}
560
12c8a1a3
JG
561struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
562 struct bt_ctf_stream_class *stream_class)
563{
564 struct bt_ctf_field_type *ret = NULL;
565
566 if (!stream_class) {
567 goto end;
568 }
569
83509119 570 bt_get(stream_class->packet_context_type);
12c8a1a3
JG
571 ret = stream_class->packet_context_type;
572end:
573 return ret;
574}
575
576int bt_ctf_stream_class_set_packet_context_type(
577 struct bt_ctf_stream_class *stream_class,
578 struct bt_ctf_field_type *packet_context_type)
579{
580 int ret = 0;
581
835b2d10 582 if (!stream_class || stream_class->frozen) {
12c8a1a3
JG
583 ret = -1;
584 goto end;
585 }
586
835b2d10
JG
587 if (packet_context_type &&
588 bt_ctf_field_type_get_type_id(packet_context_type) !=
1487a16a 589 BT_CTF_FIELD_TYPE_ID_STRUCT) {
835b2d10 590 /* A packet context must be a structure. */
12c8a1a3
JG
591 ret = -1;
592 goto end;
593 }
594
83509119
JG
595 bt_put(stream_class->packet_context_type);
596 bt_get(packet_context_type);
12c8a1a3
JG
597 stream_class->packet_context_type = packet_context_type;
598end:
599 return ret;
600}
601
662e778c
JG
602struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
603 struct bt_ctf_stream_class *stream_class)
604{
605 struct bt_ctf_field_type *ret = NULL;
606
607 if (!stream_class || !stream_class->event_header_type) {
608 goto end;
609 }
610
83509119 611 bt_get(stream_class->event_header_type);
662e778c
JG
612 ret = stream_class->event_header_type;
613end:
614 return ret;
615}
616
617int bt_ctf_stream_class_set_event_header_type(
618 struct bt_ctf_stream_class *stream_class,
619 struct bt_ctf_field_type *event_header_type)
620{
621 int ret = 0;
622
835b2d10 623 if (!stream_class || stream_class->frozen) {
662e778c
JG
624 ret = -1;
625 goto end;
626 }
627
835b2d10
JG
628 if (event_header_type &&
629 bt_ctf_field_type_get_type_id(event_header_type) !=
1487a16a 630 BT_CTF_FIELD_TYPE_ID_STRUCT) {
835b2d10 631 /* An event header must be a structure. */
662e778c
JG
632 ret = -1;
633 goto end;
634 }
635
83509119 636 bt_put(stream_class->event_header_type);
835b2d10 637 stream_class->event_header_type = bt_get(event_header_type);
662e778c
JG
638end:
639 return ret;
640}
641
af181248
JG
642struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
643 struct bt_ctf_stream_class *stream_class)
644{
645 struct bt_ctf_field_type *ret = NULL;
646
647 if (!stream_class || !stream_class->event_context_type) {
648 goto end;
649 }
650
83509119 651 bt_get(stream_class->event_context_type);
af181248
JG
652 ret = stream_class->event_context_type;
653end:
654 return ret;
655}
656
657int bt_ctf_stream_class_set_event_context_type(
658 struct bt_ctf_stream_class *stream_class,
659 struct bt_ctf_field_type *event_context_type)
660{
661 int ret = 0;
662
835b2d10 663 if (!stream_class || stream_class->frozen) {
af181248
JG
664 ret = -1;
665 goto end;
666 }
667
835b2d10
JG
668 if (event_context_type &&
669 bt_ctf_field_type_get_type_id(event_context_type) !=
1487a16a 670 BT_CTF_FIELD_TYPE_ID_STRUCT) {
835b2d10 671 /* A packet context must be a structure. */
af181248
JG
672 ret = -1;
673 goto end;
674 }
675
83509119 676 bt_put(stream_class->event_context_type);
835b2d10 677 stream_class->event_context_type = bt_get(event_context_type);
af181248
JG
678end:
679 return ret;
680}
681
11b0cdc8
JG
682void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
683{
83509119 684 bt_get(stream_class);
11b0cdc8
JG
685}
686
687void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
688{
83509119 689 bt_put(stream_class);
11b0cdc8
JG
690}
691
8bf65fbd 692static
544d0515 693int64_t get_event_class_count(void *element)
8bf65fbd
JG
694{
695 return bt_ctf_stream_class_get_event_class_count(
696 (struct bt_ctf_stream_class *) element);
697}
698
699static
700void *get_event_class(void *element, int i)
701{
9ac68eb1 702 return bt_ctf_stream_class_get_event_class_by_index(
8bf65fbd
JG
703 (struct bt_ctf_stream_class *) element, i);
704}
705
706static
d9a13d86 707int visit_event_class(void *object, bt_ctf_visitor visitor,void *data)
8bf65fbd 708{
d9a13d86
PP
709 struct bt_ctf_object obj =
710 { .object = object,
711 .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
8bf65fbd 712
d9a13d86 713 return visitor(&obj, data);
8bf65fbd
JG
714}
715
716int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
d9a13d86 717 bt_ctf_visitor visitor, void *data)
8bf65fbd
JG
718{
719 int ret;
d9a13d86
PP
720 struct bt_ctf_object obj =
721 { .object = stream_class,
722 .type = BT_CTF_OBJECT_TYPE_STREAM_CLASS };
8bf65fbd
JG
723
724 if (!stream_class || !visitor) {
725 ret = -1;
726 goto end;
727 }
728
d9a13d86 729 ret = visitor_helper(&obj, get_event_class_count,
8bf65fbd
JG
730 get_event_class,
731 visit_event_class, visitor, data);
732end:
733 return ret;
734}
735
11b0cdc8
JG
736BT_HIDDEN
737void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
738{
739 if (!stream_class) {
740 return;
741 }
742
743 stream_class->frozen = 1;
662e778c 744 bt_ctf_field_type_freeze(stream_class->event_header_type);
12c8a1a3 745 bt_ctf_field_type_freeze(stream_class->packet_context_type);
af181248 746 bt_ctf_field_type_freeze(stream_class->event_context_type);
ac0c6bdd
PP
747
748 if (stream_class->clock) {
749 bt_ctf_clock_class_freeze(stream_class->clock->clock_class);
750 }
11b0cdc8
JG
751}
752
11b0cdc8
JG
753BT_HIDDEN
754int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
755 struct metadata_context *context)
756{
9ac68eb1 757 int ret = 0;
11b0cdc8
JG
758 size_t i;
759
760 g_string_assign(context->field_name, "");
761 context->current_indentation_level = 1;
762 if (!stream_class->id_set) {
763 ret = -1;
764 goto end;
765 }
766
767 g_string_append_printf(context->string,
9ac68eb1 768 "stream {\n\tid = %" PRId64 ";\n\tevent.header := ",
11b0cdc8
JG
769 stream_class->id);
770 ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
771 context);
772 if (ret) {
773 goto end;
774 }
775
98edd02c
JG
776 if (stream_class->packet_context_type) {
777 g_string_append(context->string, ";\n\n\tpacket.context := ");
778 ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
779 context);
780 if (ret) {
781 goto end;
782 }
11b0cdc8
JG
783 }
784
785 if (stream_class->event_context_type) {
786 g_string_append(context->string, ";\n\n\tevent.context := ");
787 ret = bt_ctf_field_type_serialize(
788 stream_class->event_context_type, context);
789 if (ret) {
790 goto end;
791 }
792 }
793
794 g_string_append(context->string, ";\n};\n\n");
11b0cdc8
JG
795 for (i = 0; i < stream_class->event_classes->len; i++) {
796 struct bt_ctf_event_class *event_class =
797 stream_class->event_classes->pdata[i];
798
11b0cdc8
JG
799 ret = bt_ctf_event_class_serialize(event_class, context);
800 if (ret) {
801 goto end;
802 }
803 }
804end:
805 context->current_indentation_level = 0;
806 return ret;
807}
808
809static
83509119 810void bt_ctf_stream_class_destroy(struct bt_object *obj)
11b0cdc8
JG
811{
812 struct bt_ctf_stream_class *stream_class;
813
83509119
JG
814 stream_class = container_of(obj, struct bt_ctf_stream_class, base);
815 bt_put(stream_class->clock);
11b0cdc8 816
0b9ce69f
JG
817 if (stream_class->event_classes_ht) {
818 g_hash_table_destroy(stream_class->event_classes_ht);
819 }
11b0cdc8
JG
820 if (stream_class->event_classes) {
821 g_ptr_array_free(stream_class->event_classes, TRUE);
822 }
823
824 if (stream_class->name) {
825 g_string_free(stream_class->name, TRUE);
826 }
827
83509119
JG
828 bt_put(stream_class->event_header_type);
829 bt_put(stream_class->packet_context_type);
830 bt_put(stream_class->event_context_type);
11b0cdc8
JG
831 g_free(stream_class);
832}
833
834static
662e778c 835int init_event_header(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
836{
837 int ret = 0;
838 struct bt_ctf_field_type *event_header_type =
839 bt_ctf_field_type_structure_create();
840 struct bt_ctf_field_type *_uint32_t =
841 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
842 struct bt_ctf_field_type *_uint64_t =
843 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
844
845 if (!event_header_type) {
846 ret = -1;
847 goto end;
848 }
849
11b0cdc8
JG
850 ret = bt_ctf_field_type_structure_add_field(event_header_type,
851 _uint32_t, "id");
852 if (ret) {
853 goto end;
854 }
855
856 ret = bt_ctf_field_type_structure_add_field(event_header_type,
857 _uint64_t, "timestamp");
858 if (ret) {
859 goto end;
860 }
861
e0e2946b 862 BT_MOVE(stream_class->event_header_type, event_header_type);
11b0cdc8
JG
863end:
864 if (ret) {
83509119 865 bt_put(event_header_type);
11b0cdc8
JG
866 }
867
83509119
JG
868 bt_put(_uint32_t);
869 bt_put(_uint64_t);
11b0cdc8
JG
870 return ret;
871}
872
873static
662e778c 874int init_packet_context(struct bt_ctf_stream_class *stream_class)
11b0cdc8
JG
875{
876 int ret = 0;
877 struct bt_ctf_field_type *packet_context_type =
878 bt_ctf_field_type_structure_create();
879 struct bt_ctf_field_type *_uint64_t =
880 get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
881
882 if (!packet_context_type) {
883 ret = -1;
884 goto end;
885 }
886
887 /*
888 * We create a stream packet context as proposed in the CTF
889 * specification.
890 */
11b0cdc8
JG
891 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
892 _uint64_t, "timestamp_begin");
893 if (ret) {
894 goto end;
895 }
896
897 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
898 _uint64_t, "timestamp_end");
899 if (ret) {
900 goto end;
901 }
902
903 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
904 _uint64_t, "content_size");
905 if (ret) {
906 goto end;
907 }
908
909 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
910 _uint64_t, "packet_size");
911 if (ret) {
912 goto end;
913 }
914
915 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
916 _uint64_t, "events_discarded");
917 if (ret) {
918 goto end;
919 }
920
e0e2946b 921 BT_MOVE(stream_class->packet_context_type, packet_context_type);
11b0cdc8
JG
922end:
923 if (ret) {
83509119 924 bt_put(packet_context_type);
11b0cdc8
JG
925 goto end;
926 }
927
83509119 928 bt_put(_uint64_t);
11b0cdc8
JG
929 return ret;
930}
This page took 0.078309 seconds and 4 git commands to generate.