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