Fix: Uninitialized return value in bt_ctf_event_class_get_id
[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/compiler.h>
40
41 static
42 void bt_ctf_event_class_destroy(struct bt_ctf_ref *ref);
43 static
44 void bt_ctf_event_destroy(struct bt_ctf_ref *ref);
45 static
46 int set_integer_field_value(struct bt_ctf_field *field, uint64_t value);
47
48 struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
49 {
50 int ret;
51 struct bt_object *obj = NULL;
52 struct bt_ctf_event_class *event_class = NULL;
53
54 if (bt_ctf_validate_identifier(name)) {
55 goto error;
56 }
57
58 event_class = g_new0(struct bt_ctf_event_class, 1);
59 if (!event_class) {
60 goto error;
61 }
62
63 bt_ctf_ref_init(&event_class->ref_count);
64 event_class->fields = bt_ctf_field_type_structure_create();
65 if (!event_class->fields) {
66 goto error;
67 }
68
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
100 return event_class;
101
102 error:
103 if (event_class) {
104 bt_ctf_event_class_put(event_class);
105 }
106
107 BT_OBJECT_PUT(obj);
108
109 return NULL;
110 }
111
112 const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
113 {
114 struct bt_object *obj = NULL;
115 const char *name = NULL;
116
117 if (!event_class) {
118 goto end;
119 }
120
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
131 end:
132 BT_OBJECT_PUT(obj);
133
134 return name;
135 }
136
137 int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
138 {
139 struct bt_object *obj = NULL;
140 int64_t ret = 0;
141
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 */
159 ret = -1;
160 goto end;
161 }
162
163 end:
164 BT_OBJECT_PUT(obj);
165
166 return ret;
167 }
168
169 int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
170 uint32_t id)
171 {
172 int ret = 0;
173 struct bt_object *obj = NULL;
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
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
200 end:
201 BT_OBJECT_PUT(obj);
202
203 return ret;
204 }
205
206 int 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
252 end:
253 return ret;
254 }
255
256 int 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
268 end:
269 return ret;
270 }
271
272 const char *
273 bt_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
285 end:
286 return ret;
287 }
288
289 struct bt_object *
290 bt_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
302 end:
303 return ret;
304 }
305
306 struct bt_object *
307 bt_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
320 end:
321 return ret;
322
323 }
324
325 struct 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);
336 end:
337 return stream_class;
338 }
339
340 struct 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;
351 end:
352 return payload;
353 }
354
355 int 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
360 if (!event_class || !payload ||
361 bt_ctf_field_type_get_type_id(payload) != CTF_TYPE_STRUCT) {
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;
369 end:
370 return ret;
371 }
372
373 int 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
379 if (!event_class || !type || bt_ctf_validate_identifier(name) ||
380 event_class->frozen) {
381 ret = -1;
382 goto end;
383 }
384
385 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
386 CTF_TYPE_STRUCT) {
387 ret = -1;
388 goto end;
389 }
390
391 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
392 type, name);
393 end:
394 return ret;
395 }
396
397 int bt_ctf_event_class_get_field_count(
398 struct bt_ctf_event_class *event_class)
399 {
400 int ret;
401
402 if (!event_class) {
403 ret = -1;
404 goto end;
405 }
406
407 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
408 CTF_TYPE_STRUCT) {
409 ret = -1;
410 goto end;
411 }
412
413 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
414 end:
415 return ret;
416 }
417
418 int 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,
420 int index)
421 {
422 int ret;
423
424 if (!event_class || index < 0) {
425 ret = -1;
426 goto end;
427 }
428
429 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
430 CTF_TYPE_STRUCT) {
431 ret = -1;
432 goto end;
433 }
434
435 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
436 field_name, field_type, index);
437 end:
438 return ret;
439 }
440
441 struct 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
451 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
452 CTF_TYPE_STRUCT) {
453 goto end;
454 }
455
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);
467 end:
468 return field_type;
469 }
470
471 struct 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;
482 end:
483 return context_type;
484 }
485
486 int 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;
505 end:
506 return ret;
507
508 }
509
510 void 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
519 void 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
528 struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
529 {
530 int ret;
531 struct bt_object *obj = NULL;
532 struct bt_ctf_event *event = NULL;
533
534 if (!event_class) {
535 goto end;
536 }
537
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) {
545 goto end;
546 }
547 assert(event_class->stream_class->event_header_type);
548
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
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 }
578 if (event_class->context) {
579 event->context_payload = bt_ctf_field_create(
580 event_class->context);
581 if (!event->context_payload) {
582 goto error_destroy;
583 }
584 }
585 event->fields_payload = bt_ctf_field_create(event_class->fields);
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);
595 end:
596 return event;
597 error_destroy:
598 if (event) {
599 bt_ctf_event_destroy(&event->ref_count);
600 }
601
602 return NULL;
603 }
604
605 struct 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);
615 end:
616 return event_class;
617 }
618
619 struct 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 }
631 end:
632 return stream;
633 }
634
635 struct 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
660 error_put_stream_class:
661 bt_ctf_stream_class_put(stream_class);
662 error_put_event_class:
663 bt_ctf_event_class_put(event_class);
664 end:
665 return clock;
666 }
667
668 int bt_ctf_event_set_payload(struct bt_ctf_event *event,
669 const char *name,
670 struct bt_ctf_field *payload)
671 {
672 int ret = 0;
673
674 if (!event || !payload) {
675 ret = -1;
676 goto end;
677 }
678
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 }
696 end:
697 return ret;
698 }
699
700
701 struct 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
706 if (!event) {
707 goto end;
708 }
709
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 }
717 end:
718 return field;
719 }
720
721 struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
722 struct bt_ctf_event *event, int index)
723 {
724 struct bt_ctf_field *field = NULL;
725
726 if (!event || index < 0) {
727 goto end;
728 }
729
730 field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
731 index);
732 end:
733 return field;
734 }
735
736 struct 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);
747 end:
748 return header;
749 }
750
751 int 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;
781 end:
782 if (field_type) {
783 bt_ctf_field_type_put(field_type);
784 }
785 return ret;
786 }
787
788 struct 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);
799 end:
800 return context;
801 }
802
803 int 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;
823 end:
824 if (field_type) {
825 bt_ctf_field_type_put(field_type);
826 }
827 return ret;
828 }
829
830 void 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
839 void 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
848 static
849 void 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
857 /*
858 * Don't call put() on the stream class. See comment in
859 * bt_ctf_event_class_set_stream_class for explanation.
860 */
861 event_class = container_of(ref, struct bt_ctf_event_class, ref_count);
862 if (event_class->attributes) {
863 bt_ctf_attributes_destroy(event_class->attributes);
864 }
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 }
871 g_free(event_class);
872 }
873
874 static
875 void 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);
885 if (event->event_class) {
886 bt_ctf_event_class_put(event->event_class);
887 }
888 if (event->event_header) {
889 bt_ctf_field_put(event->event_header);
890 }
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 }
897 g_free(event);
898 }
899
900 static
901 int 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 }
938 end:
939 bt_ctf_field_type_put(field_type);
940 return ret;
941 }
942
943 BT_HIDDEN
944 void 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);
950 bt_ctf_attributes_freeze(event_class->attributes);
951 }
952
953 BT_HIDDEN
954 int bt_ctf_event_class_set_stream_class(struct bt_ctf_event_class *event_class,
955 struct bt_ctf_stream_class *stream_class)
956 {
957 int ret = 0;
958
959 if (!event_class) {
960 ret = -1;
961 goto end;
962 }
963
964 /* Allow a NULL stream_class to unset the current stream_class */
965 if (stream_class && event_class->stream_class) {
966 ret = -1;
967 goto end;
968 }
969
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 */
979 end:
980 return ret;
981 }
982
983 BT_HIDDEN
984 int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
985 struct metadata_context *context)
986 {
987 int i;
988 int count;
989 int ret = 0;
990 struct bt_object *attr_value = NULL;
991
992 assert(event_class);
993 assert(context);
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) {
1001 ret = -1;
1002 goto end;
1003 }
1004
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 }
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");
1078 end:
1079 context->current_indentation_level = 0;
1080 BT_OBJECT_PUT(attr_value);
1081 return ret;
1082 }
1083
1084 void 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
1098 BT_HIDDEN
1099 int 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);
1105 ret = bt_ctf_field_validate(event->event_header);
1106 if (ret) {
1107 goto end;
1108 }
1109
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 }
1118 end:
1119 return ret;
1120 }
1121
1122 BT_HIDDEN
1123 int 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 }
1143 end:
1144 return ret;
1145 }
1146
1147 BT_HIDDEN
1148 int 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,
1161 (uint64_t) bt_ctf_event_class_get_id(
1162 event->event_class));
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) {
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 }
1193 }
1194 }
1195 end:
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 }
1204
1205 BT_HIDDEN
1206 int 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;
1223 end:
1224 return ret;
1225 }
This page took 0.074456 seconds and 5 git commands to generate.