ir: add tests for bt_ctf_event's stream accessor
[babeltrace.git] / formats / ctf / ir / event.c
CommitLineData
273b65be
JG
1/*
2 * event.c
3 *
d2dc44b6 4 * Babeltrace CTF IR - Event
273b65be 5 *
de9dd397 6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
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/event.h>
30#include <babeltrace/ctf-writer/event-types.h>
31#include <babeltrace/ctf-writer/event-fields.h>
adc315b8
JG
32#include <babeltrace/ctf-ir/event-fields-internal.h>
33#include <babeltrace/ctf-ir/event-types-internal.h>
34#include <babeltrace/ctf-ir/event-internal.h>
2f100782 35#include <babeltrace/ctf-ir/stream-class.h>
c35a1669 36#include <babeltrace/ctf-ir/stream-class-internal.h>
bc37ae52 37#include <babeltrace/ctf-ir/trace-internal.h>
654c1444 38#include <babeltrace/ctf-ir/utils.h>
273b65be
JG
39#include <babeltrace/compiler.h>
40
41static
42void bt_ctf_event_class_destroy(struct bt_ctf_ref *ref);
43static
44void bt_ctf_event_destroy(struct bt_ctf_ref *ref);
662e778c
JG
45static
46int set_integer_field_value(struct bt_ctf_field *field, uint64_t value);
273b65be
JG
47
48struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
49{
b8248cc0
PP
50 int ret;
51 struct bt_object *obj = NULL;
273b65be
JG
52 struct bt_ctf_event_class *event_class = NULL;
53
654c1444 54 if (bt_ctf_validate_identifier(name)) {
b8248cc0 55 goto error;
273b65be
JG
56 }
57
58 event_class = g_new0(struct bt_ctf_event_class, 1);
59 if (!event_class) {
b8248cc0 60 goto error;
273b65be
JG
61 }
62
63 bt_ctf_ref_init(&event_class->ref_count);
c5a9aa19
JG
64 event_class->fields = bt_ctf_field_type_structure_create();
65 if (!event_class->fields) {
b8248cc0 66 goto error;
c5a9aa19
JG
67 }
68
b8248cc0
PP
69 event_class->attributes = bt_ctf_attributes_create();
70 if (!event_class->attributes) {
71 goto error;
72 }
73
74 obj = bt_object_integer_create_init(-1);
75 if (!obj) {
76 goto error;
77 }
78
79 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
80 "id", obj);
81 if (ret) {
82 goto error;
83 }
84
85 BT_OBJECT_PUT(obj);
86
87 obj = bt_object_string_create_init(name);
88 if (!obj) {
89 goto error;
90 }
91
92 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
93 "name", obj);
94 if (ret) {
95 goto error;
96 }
97
98 BT_OBJECT_PUT(obj);
99
273b65be 100 return event_class;
b8248cc0
PP
101
102error:
103 if (event_class) {
104 bt_ctf_event_class_put(event_class);
105 }
106
107 BT_OBJECT_PUT(obj);
108
109 return NULL;
273b65be
JG
110}
111
2f100782
JG
112const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
113{
b8248cc0 114 struct bt_object *obj = NULL;
2f100782
JG
115 const char *name = NULL;
116
117 if (!event_class) {
118 goto end;
119 }
120
b8248cc0
PP
121 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
122 BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
123 if (!obj) {
124 goto end;
125 }
126
127 if (bt_object_string_get(obj, &name)) {
128 name = NULL;
129 }
130
2f100782 131end:
b8248cc0
PP
132 BT_OBJECT_PUT(obj);
133
2f100782
JG
134 return name;
135}
136
137int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
138{
b8248cc0 139 struct bt_object *obj = NULL;
2f100782
JG
140 int64_t ret;
141
b8248cc0
PP
142 if (!event_class) {
143 ret = -1;
144 goto end;
145 }
146
147 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
148 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
149 if (!obj) {
150 goto end;
151 }
152
153 if (bt_object_integer_get(obj, &ret)) {
154 ret = -1;
155 }
156
157 if (ret < 0) {
158 /* means ID is not set */
2f100782
JG
159 ret = -1;
160 goto end;
161 }
162
2f100782 163end:
b8248cc0
PP
164 BT_OBJECT_PUT(obj);
165
2f100782
JG
166 return ret;
167}
168
169int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
170 uint32_t id)
171{
172 int ret = 0;
b8248cc0 173 struct bt_object *obj = NULL;
2f100782
JG
174
175 if (!event_class) {
176 ret = -1;
177 goto end;
178 }
179
180 if (event_class->stream_class) {
181 /*
182 * We don't allow changing the id if the event class has already
183 * been added to a stream class.
184 */
185 ret = -1;
186 goto end;
187 }
188
b8248cc0
PP
189 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
190 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
191 if (!obj) {
192 goto end;
193 }
194
195 if (bt_object_integer_set(obj, id)) {
196 ret = -1;
197 goto end;
198 }
199
200end:
201 BT_OBJECT_PUT(obj);
202
203 return ret;
204}
205
206int bt_ctf_event_class_set_attribute(
207 struct bt_ctf_event_class *event_class, const char *name,
208 struct bt_object *value)
209{
210 int ret = 0;
211
212 if (!event_class || !name || !value || event_class->frozen) {
213 ret = -1;
214 goto end;
215 }
216
217 if (!strcmp(name, "id") || !strcmp(name, "loglevel")) {
218 if (!bt_object_is_integer(value)) {
219 ret = -1;
220 goto end;
221 }
222 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri")) {
223 if (!bt_object_is_string(value)) {
224 ret = -1;
225 goto end;
226 }
227 } else {
228 /* unknown attribute */
229 ret = -1;
230 goto end;
231 }
232
233 /* "id" special case: >= 0 */
234 if (!strcmp(name, "id")) {
235 int64_t val;
236
237 ret = bt_object_integer_get(value, &val);
238
239 if (ret) {
240 goto end;
241 }
242
243 if (val < 0) {
244 ret = -1;
245 goto end;
246 }
247 }
248
249 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
250 name, value);
251
2f100782
JG
252end:
253 return ret;
254}
255
b8248cc0
PP
256int bt_ctf_event_class_get_attribute_count(
257 struct bt_ctf_event_class *event_class)
258{
259 int ret = 0;
260
261 if (!event_class) {
262 ret = -1;
263 goto end;
264 }
265
266 ret = bt_ctf_attributes_get_count(event_class->attributes);
267
268end:
269 return ret;
270}
271
272const char *
273bt_ctf_event_class_get_attribute_name(
274 struct bt_ctf_event_class *event_class, int index)
275{
276 const char *ret;
277
278 if (!event_class) {
279 ret = NULL;
280 goto end;
281 }
282
283 ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
284
285end:
286 return ret;
287}
288
289struct bt_object *
290bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
291 int index)
292{
293 struct bt_object *ret;
294
295 if (!event_class) {
296 ret = NULL;
297 goto end;
298 }
299
300 ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
301
302end:
303 return ret;
304}
305
306struct bt_object *
307bt_ctf_event_class_get_attribute_value_by_name(
308 struct bt_ctf_event_class *event_class, const char *name)
309{
310 struct bt_object *ret;
311
312 if (!event_class || !name) {
313 ret = NULL;
314 goto end;
315 }
316
317 ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
318 name);
319
320end:
321 return ret;
322
323}
324
2f100782
JG
325struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
326 struct bt_ctf_event_class *event_class)
327{
328 struct bt_ctf_stream_class *stream_class = NULL;
329
330 if (!event_class) {
331 goto end;
332 }
333
334 stream_class = event_class->stream_class;
335 bt_ctf_stream_class_get(stream_class);
336end:
337 return stream_class;
338}
339
c5a9aa19
JG
340struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
341 struct bt_ctf_event_class *event_class)
342{
343 struct bt_ctf_field_type *payload = NULL;
344
345 if (!event_class) {
346 goto end;
347 }
348
349 bt_ctf_field_type_get(event_class->fields);
350 payload = event_class->fields;
351end:
352 return payload;
353}
354
355int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
356 struct bt_ctf_field_type *payload)
357{
358 int ret = 0;
359
d2127f80
JG
360 if (!event_class || !payload ||
361 bt_ctf_field_type_get_type_id(payload) != CTF_TYPE_STRUCT) {
c5a9aa19
JG
362 ret = -1;
363 goto end;
364 }
365
366 bt_ctf_field_type_get(payload);
367 bt_ctf_field_type_put(event_class->fields);
368 event_class->fields = payload;
369end:
370 return ret;
371}
372
273b65be
JG
373int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
374 struct bt_ctf_field_type *type,
375 const char *name)
376{
377 int ret = 0;
378
654c1444 379 if (!event_class || !type || bt_ctf_validate_identifier(name) ||
273b65be
JG
380 event_class->frozen) {
381 ret = -1;
382 goto end;
383 }
384
c5a9aa19
JG
385 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
386 CTF_TYPE_STRUCT) {
387 ret = -1;
388 goto end;
273b65be
JG
389 }
390
391 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
392 type, name);
393end:
394 return ret;
395}
396
074ee56d 397int bt_ctf_event_class_get_field_count(
2f100782
JG
398 struct bt_ctf_event_class *event_class)
399{
074ee56d 400 int ret;
2f100782
JG
401
402 if (!event_class) {
403 ret = -1;
404 goto end;
405 }
406
c5a9aa19
JG
407 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
408 CTF_TYPE_STRUCT) {
409 ret = -1;
410 goto end;
411 }
412
2f100782
JG
413 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
414end:
415 return ret;
416}
417
418int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class,
419 const char **field_name, struct bt_ctf_field_type **field_type,
074ee56d 420 int index)
2f100782
JG
421{
422 int ret;
423
074ee56d 424 if (!event_class || index < 0) {
2f100782
JG
425 ret = -1;
426 goto end;
427 }
428
c5a9aa19
JG
429 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
430 CTF_TYPE_STRUCT) {
431 ret = -1;
432 goto end;
433 }
434
2f100782
JG
435 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
436 field_name, field_type, index);
437end:
438 return ret;
439}
440
441struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
442 struct bt_ctf_event_class *event_class, const char *name)
443{
444 GQuark name_quark;
445 struct bt_ctf_field_type *field_type = NULL;
446
447 if (!event_class || !name) {
448 goto end;
449 }
450
c5a9aa19
JG
451 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
452 CTF_TYPE_STRUCT) {
453 goto end;
454 }
455
2f100782
JG
456 name_quark = g_quark_try_string(name);
457 if (!name_quark) {
458 goto end;
459 }
460
461 /*
462 * No need to increment field_type's reference count since getting it
463 * from the structure already does.
464 */
465 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
466 event_class->fields, name);
467end:
468 return field_type;
469}
470
f655a84d
JG
471struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
472 struct bt_ctf_event_class *event_class)
473{
474 struct bt_ctf_field_type *context_type = NULL;
475
476 if (!event_class || !event_class->context) {
477 goto end;
478 }
479
480 bt_ctf_field_type_get(event_class->context);
481 context_type = event_class->context;
482end:
483 return context_type;
484}
485
486int bt_ctf_event_class_set_context_type(
487 struct bt_ctf_event_class *event_class,
488 struct bt_ctf_field_type *context)
489{
490 int ret = 0;
491
492 if (!event_class || !context || event_class->frozen) {
493 ret = -1;
494 goto end;
495 }
496
497 if (bt_ctf_field_type_get_type_id(context) != CTF_TYPE_STRUCT) {
498 ret = -1;
499 goto end;
500 }
501
502 bt_ctf_field_type_get(context);
503 bt_ctf_field_type_put(event_class->context);
504 event_class->context = context;
505end:
506 return ret;
507
508}
509
273b65be
JG
510void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
511{
512 if (!event_class) {
513 return;
514 }
515
516 bt_ctf_ref_get(&event_class->ref_count);
517}
518
519void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
520{
521 if (!event_class) {
522 return;
523 }
524
525 bt_ctf_ref_put(&event_class->ref_count, bt_ctf_event_class_destroy);
526}
527
528struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
529{
b8248cc0
PP
530 int ret;
531 struct bt_object *obj = NULL;
273b65be
JG
532 struct bt_ctf_event *event = NULL;
533
534 if (!event_class) {
535 goto end;
536 }
537
662e778c
JG
538 /*
539 * The event class does not keep ownership of the stream class to
540 * which it as been added. Therefore, it can't assume it has been
541 * set. However, we disallow the creation of an event if its
542 * associated stream class has been reclaimed.
543 */
544 if (!event_class->stream_class) {
b8248cc0 545 goto end;
662e778c
JG
546 }
547 assert(event_class->stream_class->event_header_type);
548
b8248cc0
PP
549 /* set "stream_id" attribute now that we know its value */
550 obj = bt_object_integer_create_init(event_class->stream_class->id);
551 if (!obj) {
552 goto end;
553 }
554
555 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
556 "stream_id", obj);
557 BT_OBJECT_PUT(obj);
558
559 if (ret) {
560 goto end;
561 }
562
563 event = g_new0(struct bt_ctf_event, 1);
564 if (!event) {
565 goto end;
566 }
567
568 bt_ctf_ref_init(&event->ref_count);
569 bt_ctf_event_class_get(event_class);
570 bt_ctf_event_class_freeze(event_class);
571 event->event_class = event_class;
572
662e778c
JG
573 event->event_header = bt_ctf_field_create(
574 event_class->stream_class->event_header_type);
575 if (!event->event_header) {
576 goto error_destroy;
577 }
f655a84d
JG
578 if (event_class->context) {
579 event->context_payload = bt_ctf_field_create(
580 event_class->context);
662e778c
JG
581 if (!event->context_payload) {
582 goto error_destroy;
583 }
f655a84d 584 }
273b65be 585 event->fields_payload = bt_ctf_field_create(event_class->fields);
662e778c
JG
586 if (!event->fields_payload) {
587 goto error_destroy;
588 }
589
590 /*
591 * Freeze the stream class since the event header must not be changed
592 * anymore.
593 */
594 bt_ctf_stream_class_freeze(event_class->stream_class);
273b65be
JG
595end:
596 return event;
662e778c 597error_destroy:
b8248cc0
PP
598 if (event) {
599 bt_ctf_event_destroy(&event->ref_count);
600 }
601
662e778c 602 return NULL;
273b65be
JG
603}
604
2f100782
JG
605struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
606{
607 struct bt_ctf_event_class *event_class = NULL;
608
609 if (!event) {
610 goto end;
611 }
612
613 event_class = event->event_class;
614 bt_ctf_event_class_get(event_class);
615end:
616 return event_class;
617}
618
8e5003bb
JG
619struct bt_ctf_stream *bt_ctf_event_get_stream(struct bt_ctf_event *event)
620{
621 struct bt_ctf_stream *stream = NULL;
622
623 if (!event) {
624 goto end;
625 }
626
627 stream = event->stream;
628 if (stream) {
629 bt_ctf_stream_get(stream);
630 }
631end:
632 return stream;
633}
634
2f100782
JG
635struct bt_ctf_clock *bt_ctf_event_get_clock(struct bt_ctf_event *event)
636{
637 struct bt_ctf_clock *clock = NULL;
638 struct bt_ctf_event_class *event_class;
639 struct bt_ctf_stream_class *stream_class;
640
641 if (!event) {
642 goto end;
643 }
644
645 event_class = bt_ctf_event_get_class(event);
646 if (!event_class) {
647 goto end;
648 }
649
650 stream_class = bt_ctf_event_class_get_stream_class(event_class);
651 if (!stream_class) {
652 goto error_put_event_class;
653 }
654
655 clock = bt_ctf_stream_class_get_clock(stream_class);
656 if (!clock) {
657 goto error_put_stream_class;
658 }
659
660error_put_stream_class:
661 bt_ctf_stream_class_put(stream_class);
662error_put_event_class:
663 bt_ctf_event_class_put(event_class);
664end:
665 return clock;
666}
667
273b65be
JG
668int bt_ctf_event_set_payload(struct bt_ctf_event *event,
669 const char *name,
c5a9aa19 670 struct bt_ctf_field *payload)
273b65be
JG
671{
672 int ret = 0;
673
c5a9aa19 674 if (!event || !payload) {
273b65be
JG
675 ret = -1;
676 goto end;
677 }
678
c5a9aa19
JG
679 if (name) {
680 ret = bt_ctf_field_structure_set_field(event->fields_payload,
681 name, payload);
682 } else {
683 struct bt_ctf_field_type *payload_type;
684
685 payload_type = bt_ctf_field_get_type(payload);
686 if (payload_type == event->event_class->fields) {
687 bt_ctf_field_put(event->fields_payload);
688 bt_ctf_field_get(payload);
689 event->fields_payload = payload;
690 } else {
691 ret = -1;
692 }
693
694 bt_ctf_field_type_put(payload_type);
695 }
273b65be
JG
696end:
697 return ret;
698}
699
700
701struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
702 const char *name)
703{
704 struct bt_ctf_field *field = NULL;
705
c5a9aa19 706 if (!event) {
273b65be
JG
707 goto end;
708 }
709
c5a9aa19
JG
710 if (name) {
711 field = bt_ctf_field_structure_get_field(event->fields_payload,
712 name);
713 } else {
714 field = event->fields_payload;
715 bt_ctf_field_get(field);
716 }
273b65be
JG
717end:
718 return field;
719}
720
2f100782 721struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
074ee56d 722 struct bt_ctf_event *event, int index)
2f100782
JG
723{
724 struct bt_ctf_field *field = NULL;
725
074ee56d 726 if (!event || index < 0) {
2f100782
JG
727 goto end;
728 }
729
730 field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
731 index);
732end:
733 return field;
734}
735
662e778c
JG
736struct bt_ctf_field *bt_ctf_event_get_event_header(
737 struct bt_ctf_event *event)
738{
739 struct bt_ctf_field *header = NULL;
740
741 if (!event || !event->event_header) {
742 goto end;
743 }
744
745 header = event->event_header;
746 bt_ctf_field_get(header);
747end:
748 return header;
749}
750
751int bt_ctf_event_set_event_header(struct bt_ctf_event *event,
752 struct bt_ctf_field *header)
753{
754 int ret = 0;
755 struct bt_ctf_field_type *field_type = NULL;
756
757 if (!event || !header) {
758 ret = -1;
759 goto end;
760 }
761
762 /* Could be NULL since an event class doesn't own a stream class */
763 if (!event->event_class->stream_class) {
764 ret = -1;
765 goto end;
766 }
767
768 /*
769 * Ensure the provided header's type matches the one registered to the
770 * stream class.
771 */
772 field_type = bt_ctf_field_get_type(header);
773 if (field_type != event->event_class->stream_class->event_header_type) {
774 ret = -1;
775 goto end;
776 }
777
778 bt_ctf_field_get(header);
779 bt_ctf_field_put(event->event_header);
780 event->event_header = header;
781end:
782 if (field_type) {
783 bt_ctf_field_type_put(field_type);
784 }
785 return ret;
786}
787
f655a84d
JG
788struct bt_ctf_field *bt_ctf_event_get_event_context(
789 struct bt_ctf_event *event)
790{
791 struct bt_ctf_field *context = NULL;
792
793 if (!event || !event->context_payload) {
794 goto end;
795 }
796
797 context = event->context_payload;
798 bt_ctf_field_get(context);
799end:
800 return context;
801}
802
803int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
804 struct bt_ctf_field *context)
805{
806 int ret = 0;
807 struct bt_ctf_field_type *field_type = NULL;
808
809 if (!event || !context) {
810 ret = -1;
811 goto end;
812 }
813
814 field_type = bt_ctf_field_get_type(context);
815 if (field_type != event->event_class->context) {
816 ret = -1;
817 goto end;
818 }
819
820 bt_ctf_field_get(context);
821 bt_ctf_field_put(event->context_payload);
822 event->context_payload = context;
823end:
824 if (field_type) {
825 bt_ctf_field_type_put(field_type);
826 }
827 return ret;
828}
829
273b65be
JG
830void bt_ctf_event_get(struct bt_ctf_event *event)
831{
832 if (!event) {
833 return;
834 }
835
836 bt_ctf_ref_get(&event->ref_count);
837}
838
839void bt_ctf_event_put(struct bt_ctf_event *event)
840{
841 if (!event) {
842 return;
843 }
844
845 bt_ctf_ref_put(&event->ref_count, bt_ctf_event_destroy);
846}
847
848static
849void bt_ctf_event_class_destroy(struct bt_ctf_ref *ref)
850{
851 struct bt_ctf_event_class *event_class;
852
853 if (!ref) {
854 return;
855 }
856
2f100782
JG
857 /*
858 * Don't call put() on the stream class. See comment in
859 * bt_ctf_event_class_set_stream_class for explanation.
860 */
273b65be 861 event_class = container_of(ref, struct bt_ctf_event_class, ref_count);
b8248cc0
PP
862 if (event_class->attributes) {
863 bt_ctf_attributes_destroy(event_class->attributes);
864 }
f655a84d
JG
865 if (event_class->context) {
866 bt_ctf_field_type_put(event_class->context);
867 }
868 if (event_class->fields) {
869 bt_ctf_field_type_put(event_class->fields);
870 }
273b65be
JG
871 g_free(event_class);
872}
873
874static
875void bt_ctf_event_destroy(struct bt_ctf_ref *ref)
876{
877 struct bt_ctf_event *event;
878
879 if (!ref) {
880 return;
881 }
882
883 event = container_of(ref, struct bt_ctf_event,
884 ref_count);
f655a84d
JG
885 if (event->event_class) {
886 bt_ctf_event_class_put(event->event_class);
887 }
662e778c
JG
888 if (event->event_header) {
889 bt_ctf_field_put(event->event_header);
890 }
f655a84d
JG
891 if (event->context_payload) {
892 bt_ctf_field_put(event->context_payload);
893 }
894 if (event->fields_payload) {
895 bt_ctf_field_put(event->fields_payload);
896 }
273b65be
JG
897 g_free(event);
898}
899
662e778c
JG
900static
901int set_integer_field_value(struct bt_ctf_field* field, uint64_t value)
902{
903 int ret = 0;
904 struct bt_ctf_field_type *field_type = NULL;
905
906 if (!field) {
907 ret = -1;
908 goto end;
909 }
910
911 if (!bt_ctf_field_validate(field)) {
912 /* Payload already set, skip! (not an error) */
913 goto end;
914 }
915
916 field_type = bt_ctf_field_get_type(field);
917 assert(field_type);
918
919 if (bt_ctf_field_type_get_type_id(field_type) != CTF_TYPE_INTEGER) {
920 /* Not an integer and the value is unset, error. */
921 ret = -1;
922 goto end;
923 }
924
925 if (bt_ctf_field_type_integer_get_signed(field_type)) {
926 ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value);
927 if (ret) {
928 /* Value is out of range, error. */
929 goto end;
930 }
931 } else {
932 ret = bt_ctf_field_unsigned_integer_set_value(field, value);
933 if (ret) {
934 /* Value is out of range, error. */
935 goto end;
936 }
937 }
938end:
939 bt_ctf_field_type_put(field_type);
940 return ret;
941}
942
273b65be
JG
943BT_HIDDEN
944void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
945{
946 assert(event_class);
947 event_class->frozen = 1;
948 bt_ctf_field_type_freeze(event_class->context);
949 bt_ctf_field_type_freeze(event_class->fields);
b8248cc0 950 bt_ctf_attributes_freeze(event_class->attributes);
273b65be
JG
951}
952
953BT_HIDDEN
2f100782
JG
954int bt_ctf_event_class_set_stream_class(struct bt_ctf_event_class *event_class,
955 struct bt_ctf_stream_class *stream_class)
273b65be
JG
956{
957 int ret = 0;
958
2f100782 959 if (!event_class) {
273b65be
JG
960 ret = -1;
961 goto end;
962 }
963
2f100782
JG
964 /* Allow a NULL stream_class to unset the current stream_class */
965 if (stream_class && event_class->stream_class) {
273b65be
JG
966 ret = -1;
967 goto end;
968 }
969
2f100782
JG
970 event_class->stream_class = stream_class;
971 /*
972 * We don't get() the stream_class since doing so would introduce
973 * a circular ownership between event classes and stream classes.
974 *
975 * A stream class will always unset itself from its events before
976 * being destroyed. This ensures that a user won't get a pointer
977 * to a stale stream class instance from an event class.
978 */
273b65be
JG
979end:
980 return ret;
981}
982
983BT_HIDDEN
984int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
985 struct metadata_context *context)
986{
b8248cc0
PP
987 int i;
988 int count;
273b65be 989 int ret = 0;
b8248cc0 990 struct bt_object *attr_value = NULL;
273b65be
JG
991
992 assert(event_class);
993 assert(context);
b8248cc0
PP
994
995 context->current_indentation_level = 1;
996 g_string_assign(context->field_name, "");
997 g_string_append(context->string, "event {\n");
998 count = bt_ctf_event_class_get_attribute_count(event_class);
999
1000 if (count < 0) {
2f100782
JG
1001 ret = -1;
1002 goto end;
1003 }
1004
b8248cc0
PP
1005 for (i = 0; i < count; ++i) {
1006 const char *attr_name = NULL;
1007
1008 attr_name = bt_ctf_event_class_get_attribute_name(
1009 event_class, i);
1010 attr_value = bt_ctf_event_class_get_attribute_value(
1011 event_class, i);
1012
1013 if (!attr_name || !attr_value) {
1014 ret = -1;
1015 goto end;
1016 }
1017
1018 switch (bt_object_get_type(attr_value)) {
1019 case BT_OBJECT_TYPE_INTEGER:
1020 {
1021 int64_t value;
1022
1023 ret = bt_object_integer_get(attr_value, &value);
1024
1025 if (ret) {
1026 goto end;
1027 }
1028
1029 g_string_append_printf(context->string,
1030 "\t%s = %" PRId64 ";\n", attr_name, value);
1031 break;
1032 }
1033
1034 case BT_OBJECT_TYPE_STRING:
1035 {
1036 const char *value;
1037
1038 ret = bt_object_string_get(attr_value, &value);
1039
1040 if (ret) {
1041 goto end;
1042 }
1043
1044 g_string_append_printf(context->string,
1045 "\t%s = \"%s\";\n", attr_name, value);
1046 break;
1047 }
1048
1049 default:
1050 /* should never happen */
1051 assert(false);
1052 break;
1053 }
1054
1055 BT_OBJECT_PUT(attr_value);
1056 }
273b65be
JG
1057
1058 if (event_class->context) {
1059 g_string_append(context->string, "\tcontext := ");
1060 ret = bt_ctf_field_type_serialize(event_class->context,
1061 context);
1062 if (ret) {
1063 goto end;
1064 }
1065 g_string_append(context->string, ";\n");
1066 }
1067
1068 if (event_class->fields) {
1069 g_string_append(context->string, "\tfields := ");
1070 ret = bt_ctf_field_type_serialize(event_class->fields, context);
1071 if (ret) {
1072 goto end;
1073 }
1074 g_string_append(context->string, ";\n");
1075 }
1076
1077 g_string_append(context->string, "};\n\n");
1078end:
1079 context->current_indentation_level = 0;
b8248cc0 1080 BT_OBJECT_PUT(attr_value);
273b65be
JG
1081 return ret;
1082}
1083
c35a1669
JG
1084void bt_ctf_event_class_set_native_byte_order(
1085 struct bt_ctf_event_class *event_class,
1086 int byte_order)
1087{
1088 if (!event_class) {
1089 return;
1090 }
1091
1092 bt_ctf_field_type_set_native_byte_order(event_class->context,
1093 byte_order);
1094 bt_ctf_field_type_set_native_byte_order(event_class->fields,
1095 byte_order);
1096}
1097
273b65be
JG
1098BT_HIDDEN
1099int bt_ctf_event_validate(struct bt_ctf_event *event)
1100{
1101 /* Make sure each field's payload has been set */
1102 int ret;
1103
1104 assert(event);
662e778c
JG
1105 ret = bt_ctf_field_validate(event->event_header);
1106 if (ret) {
1107 goto end;
1108 }
1109
273b65be
JG
1110 ret = bt_ctf_field_validate(event->fields_payload);
1111 if (ret) {
1112 goto end;
1113 }
1114
1115 if (event->event_class->context) {
1116 ret = bt_ctf_field_validate(event->context_payload);
1117 }
1118end:
1119 return ret;
1120}
1121
1122BT_HIDDEN
1123int bt_ctf_event_serialize(struct bt_ctf_event *event,
1124 struct ctf_stream_pos *pos)
1125{
1126 int ret = 0;
1127
1128 assert(event);
1129 assert(pos);
1130 if (event->context_payload) {
1131 ret = bt_ctf_field_serialize(event->context_payload, pos);
1132 if (ret) {
1133 goto end;
1134 }
1135 }
1136
1137 if (event->fields_payload) {
1138 ret = bt_ctf_field_serialize(event->fields_payload, pos);
1139 if (ret) {
1140 goto end;
1141 }
1142 }
1143end:
1144 return ret;
1145}
1146
662e778c
JG
1147BT_HIDDEN
1148int bt_ctf_event_populate_event_header(struct bt_ctf_event *event)
1149{
1150 int ret = 0;
1151 struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL;
1152
1153 if (!event) {
1154 ret = -1;
1155 goto end;
1156 }
1157
1158 id_field = bt_ctf_field_structure_get_field(event->event_header, "id");
1159 if (id_field) {
1160 ret = set_integer_field_value(id_field,
b8248cc0
PP
1161 (uint64_t) bt_ctf_event_class_get_id(
1162 event->event_class));
662e778c
JG
1163 if (ret) {
1164 goto end;
1165 }
1166 }
1167
1168 timestamp_field = bt_ctf_field_structure_get_field(event->event_header,
1169 "timestamp");
1170 if (timestamp_field) {
9a220c32
JG
1171 struct bt_ctf_field_type *timestamp_field_type =
1172 bt_ctf_field_get_type(timestamp_field);
1173 struct bt_ctf_clock *mapped_clock;
1174
1175 assert(timestamp_field_type);
1176 mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
1177 timestamp_field_type);
1178 bt_ctf_field_type_put(timestamp_field_type);
1179 if (mapped_clock) {
1180 uint64_t timestamp = bt_ctf_clock_get_time(
1181 mapped_clock);
1182
1183 bt_ctf_clock_put(mapped_clock);
1184 if (timestamp == (uint64_t) -1ULL) {
1185 goto end;
1186 }
1187
1188 ret = set_integer_field_value(timestamp_field,
1189 timestamp);
1190 if (ret) {
1191 goto end;
1192 }
662e778c
JG
1193 }
1194 }
1195end:
1196 if (id_field) {
1197 bt_ctf_field_put(id_field);
1198 }
1199 if (timestamp_field) {
1200 bt_ctf_field_put(timestamp_field);
1201 }
1202 return ret;
1203}
123fbdec
JG
1204
1205BT_HIDDEN
1206int bt_ctf_event_set_stream(struct bt_ctf_event *event,
1207 struct bt_ctf_stream *stream)
1208{
1209 int ret = 0;
1210
1211 if (!event) {
1212 ret = -1;
1213 goto end;
1214 }
1215
1216 if (event->stream && stream) {
1217 /* Already attached to a stream */
1218 ret = -1;
1219 goto end;
1220 }
1221
1222 event->stream = stream;
1223end:
1224 return ret;
1225}
This page took 0.07582 seconds and 4 git commands to generate.