ir: add attributes support to event classes
[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;
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_clock *bt_ctf_event_get_clock(struct bt_ctf_event *event)
620 {
621 struct bt_ctf_clock *clock = NULL;
622 struct bt_ctf_event_class *event_class;
623 struct bt_ctf_stream_class *stream_class;
624
625 if (!event) {
626 goto end;
627 }
628
629 event_class = bt_ctf_event_get_class(event);
630 if (!event_class) {
631 goto end;
632 }
633
634 stream_class = bt_ctf_event_class_get_stream_class(event_class);
635 if (!stream_class) {
636 goto error_put_event_class;
637 }
638
639 clock = bt_ctf_stream_class_get_clock(stream_class);
640 if (!clock) {
641 goto error_put_stream_class;
642 }
643
644 error_put_stream_class:
645 bt_ctf_stream_class_put(stream_class);
646 error_put_event_class:
647 bt_ctf_event_class_put(event_class);
648 end:
649 return clock;
650 }
651
652 int bt_ctf_event_set_payload(struct bt_ctf_event *event,
653 const char *name,
654 struct bt_ctf_field *payload)
655 {
656 int ret = 0;
657
658 if (!event || !payload) {
659 ret = -1;
660 goto end;
661 }
662
663 if (name) {
664 ret = bt_ctf_field_structure_set_field(event->fields_payload,
665 name, payload);
666 } else {
667 struct bt_ctf_field_type *payload_type;
668
669 payload_type = bt_ctf_field_get_type(payload);
670 if (payload_type == event->event_class->fields) {
671 bt_ctf_field_put(event->fields_payload);
672 bt_ctf_field_get(payload);
673 event->fields_payload = payload;
674 } else {
675 ret = -1;
676 }
677
678 bt_ctf_field_type_put(payload_type);
679 }
680 end:
681 return ret;
682 }
683
684
685 struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
686 const char *name)
687 {
688 struct bt_ctf_field *field = NULL;
689
690 if (!event) {
691 goto end;
692 }
693
694 if (name) {
695 field = bt_ctf_field_structure_get_field(event->fields_payload,
696 name);
697 } else {
698 field = event->fields_payload;
699 bt_ctf_field_get(field);
700 }
701 end:
702 return field;
703 }
704
705 struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
706 struct bt_ctf_event *event, int index)
707 {
708 struct bt_ctf_field *field = NULL;
709
710 if (!event || index < 0) {
711 goto end;
712 }
713
714 field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
715 index);
716 end:
717 return field;
718 }
719
720 struct bt_ctf_field *bt_ctf_event_get_event_header(
721 struct bt_ctf_event *event)
722 {
723 struct bt_ctf_field *header = NULL;
724
725 if (!event || !event->event_header) {
726 goto end;
727 }
728
729 header = event->event_header;
730 bt_ctf_field_get(header);
731 end:
732 return header;
733 }
734
735 int bt_ctf_event_set_event_header(struct bt_ctf_event *event,
736 struct bt_ctf_field *header)
737 {
738 int ret = 0;
739 struct bt_ctf_field_type *field_type = NULL;
740
741 if (!event || !header) {
742 ret = -1;
743 goto end;
744 }
745
746 /* Could be NULL since an event class doesn't own a stream class */
747 if (!event->event_class->stream_class) {
748 ret = -1;
749 goto end;
750 }
751
752 /*
753 * Ensure the provided header's type matches the one registered to the
754 * stream class.
755 */
756 field_type = bt_ctf_field_get_type(header);
757 if (field_type != event->event_class->stream_class->event_header_type) {
758 ret = -1;
759 goto end;
760 }
761
762 bt_ctf_field_get(header);
763 bt_ctf_field_put(event->event_header);
764 event->event_header = header;
765 end:
766 if (field_type) {
767 bt_ctf_field_type_put(field_type);
768 }
769 return ret;
770 }
771
772 struct bt_ctf_field *bt_ctf_event_get_event_context(
773 struct bt_ctf_event *event)
774 {
775 struct bt_ctf_field *context = NULL;
776
777 if (!event || !event->context_payload) {
778 goto end;
779 }
780
781 context = event->context_payload;
782 bt_ctf_field_get(context);
783 end:
784 return context;
785 }
786
787 int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
788 struct bt_ctf_field *context)
789 {
790 int ret = 0;
791 struct bt_ctf_field_type *field_type = NULL;
792
793 if (!event || !context) {
794 ret = -1;
795 goto end;
796 }
797
798 field_type = bt_ctf_field_get_type(context);
799 if (field_type != event->event_class->context) {
800 ret = -1;
801 goto end;
802 }
803
804 bt_ctf_field_get(context);
805 bt_ctf_field_put(event->context_payload);
806 event->context_payload = context;
807 end:
808 if (field_type) {
809 bt_ctf_field_type_put(field_type);
810 }
811 return ret;
812 }
813
814 void bt_ctf_event_get(struct bt_ctf_event *event)
815 {
816 if (!event) {
817 return;
818 }
819
820 bt_ctf_ref_get(&event->ref_count);
821 }
822
823 void bt_ctf_event_put(struct bt_ctf_event *event)
824 {
825 if (!event) {
826 return;
827 }
828
829 bt_ctf_ref_put(&event->ref_count, bt_ctf_event_destroy);
830 }
831
832 static
833 void bt_ctf_event_class_destroy(struct bt_ctf_ref *ref)
834 {
835 struct bt_ctf_event_class *event_class;
836
837 if (!ref) {
838 return;
839 }
840
841 /*
842 * Don't call put() on the stream class. See comment in
843 * bt_ctf_event_class_set_stream_class for explanation.
844 */
845 event_class = container_of(ref, struct bt_ctf_event_class, ref_count);
846 if (event_class->attributes) {
847 bt_ctf_attributes_destroy(event_class->attributes);
848 }
849 if (event_class->context) {
850 bt_ctf_field_type_put(event_class->context);
851 }
852 if (event_class->fields) {
853 bt_ctf_field_type_put(event_class->fields);
854 }
855 g_free(event_class);
856 }
857
858 static
859 void bt_ctf_event_destroy(struct bt_ctf_ref *ref)
860 {
861 struct bt_ctf_event *event;
862
863 if (!ref) {
864 return;
865 }
866
867 event = container_of(ref, struct bt_ctf_event,
868 ref_count);
869 if (event->event_class) {
870 bt_ctf_event_class_put(event->event_class);
871 }
872 if (event->event_header) {
873 bt_ctf_field_put(event->event_header);
874 }
875 if (event->context_payload) {
876 bt_ctf_field_put(event->context_payload);
877 }
878 if (event->fields_payload) {
879 bt_ctf_field_put(event->fields_payload);
880 }
881 g_free(event);
882 }
883
884 static
885 int set_integer_field_value(struct bt_ctf_field* field, uint64_t value)
886 {
887 int ret = 0;
888 struct bt_ctf_field_type *field_type = NULL;
889
890 if (!field) {
891 ret = -1;
892 goto end;
893 }
894
895 if (!bt_ctf_field_validate(field)) {
896 /* Payload already set, skip! (not an error) */
897 goto end;
898 }
899
900 field_type = bt_ctf_field_get_type(field);
901 assert(field_type);
902
903 if (bt_ctf_field_type_get_type_id(field_type) != CTF_TYPE_INTEGER) {
904 /* Not an integer and the value is unset, error. */
905 ret = -1;
906 goto end;
907 }
908
909 if (bt_ctf_field_type_integer_get_signed(field_type)) {
910 ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value);
911 if (ret) {
912 /* Value is out of range, error. */
913 goto end;
914 }
915 } else {
916 ret = bt_ctf_field_unsigned_integer_set_value(field, value);
917 if (ret) {
918 /* Value is out of range, error. */
919 goto end;
920 }
921 }
922 end:
923 bt_ctf_field_type_put(field_type);
924 return ret;
925 }
926
927 BT_HIDDEN
928 void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
929 {
930 assert(event_class);
931 event_class->frozen = 1;
932 bt_ctf_field_type_freeze(event_class->context);
933 bt_ctf_field_type_freeze(event_class->fields);
934 bt_ctf_attributes_freeze(event_class->attributes);
935 }
936
937 BT_HIDDEN
938 int bt_ctf_event_class_set_stream_class(struct bt_ctf_event_class *event_class,
939 struct bt_ctf_stream_class *stream_class)
940 {
941 int ret = 0;
942
943 if (!event_class) {
944 ret = -1;
945 goto end;
946 }
947
948 /* Allow a NULL stream_class to unset the current stream_class */
949 if (stream_class && event_class->stream_class) {
950 ret = -1;
951 goto end;
952 }
953
954 event_class->stream_class = stream_class;
955 /*
956 * We don't get() the stream_class since doing so would introduce
957 * a circular ownership between event classes and stream classes.
958 *
959 * A stream class will always unset itself from its events before
960 * being destroyed. This ensures that a user won't get a pointer
961 * to a stale stream class instance from an event class.
962 */
963 end:
964 return ret;
965 }
966
967 BT_HIDDEN
968 int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
969 struct metadata_context *context)
970 {
971 int i;
972 int count;
973 int ret = 0;
974 struct bt_object *attr_value = NULL;
975
976 assert(event_class);
977 assert(context);
978
979 context->current_indentation_level = 1;
980 g_string_assign(context->field_name, "");
981 g_string_append(context->string, "event {\n");
982 count = bt_ctf_event_class_get_attribute_count(event_class);
983
984 if (count < 0) {
985 ret = -1;
986 goto end;
987 }
988
989 for (i = 0; i < count; ++i) {
990 const char *attr_name = NULL;
991
992 attr_name = bt_ctf_event_class_get_attribute_name(
993 event_class, i);
994 attr_value = bt_ctf_event_class_get_attribute_value(
995 event_class, i);
996
997 if (!attr_name || !attr_value) {
998 ret = -1;
999 goto end;
1000 }
1001
1002 switch (bt_object_get_type(attr_value)) {
1003 case BT_OBJECT_TYPE_INTEGER:
1004 {
1005 int64_t value;
1006
1007 ret = bt_object_integer_get(attr_value, &value);
1008
1009 if (ret) {
1010 goto end;
1011 }
1012
1013 g_string_append_printf(context->string,
1014 "\t%s = %" PRId64 ";\n", attr_name, value);
1015 break;
1016 }
1017
1018 case BT_OBJECT_TYPE_STRING:
1019 {
1020 const char *value;
1021
1022 ret = bt_object_string_get(attr_value, &value);
1023
1024 if (ret) {
1025 goto end;
1026 }
1027
1028 g_string_append_printf(context->string,
1029 "\t%s = \"%s\";\n", attr_name, value);
1030 break;
1031 }
1032
1033 default:
1034 /* should never happen */
1035 assert(false);
1036 break;
1037 }
1038
1039 BT_OBJECT_PUT(attr_value);
1040 }
1041
1042 if (event_class->context) {
1043 g_string_append(context->string, "\tcontext := ");
1044 ret = bt_ctf_field_type_serialize(event_class->context,
1045 context);
1046 if (ret) {
1047 goto end;
1048 }
1049 g_string_append(context->string, ";\n");
1050 }
1051
1052 if (event_class->fields) {
1053 g_string_append(context->string, "\tfields := ");
1054 ret = bt_ctf_field_type_serialize(event_class->fields, context);
1055 if (ret) {
1056 goto end;
1057 }
1058 g_string_append(context->string, ";\n");
1059 }
1060
1061 g_string_append(context->string, "};\n\n");
1062 end:
1063 context->current_indentation_level = 0;
1064 BT_OBJECT_PUT(attr_value);
1065 return ret;
1066 }
1067
1068 void bt_ctf_event_class_set_native_byte_order(
1069 struct bt_ctf_event_class *event_class,
1070 int byte_order)
1071 {
1072 if (!event_class) {
1073 return;
1074 }
1075
1076 bt_ctf_field_type_set_native_byte_order(event_class->context,
1077 byte_order);
1078 bt_ctf_field_type_set_native_byte_order(event_class->fields,
1079 byte_order);
1080 }
1081
1082 BT_HIDDEN
1083 int bt_ctf_event_validate(struct bt_ctf_event *event)
1084 {
1085 /* Make sure each field's payload has been set */
1086 int ret;
1087
1088 assert(event);
1089 ret = bt_ctf_field_validate(event->event_header);
1090 if (ret) {
1091 goto end;
1092 }
1093
1094 ret = bt_ctf_field_validate(event->fields_payload);
1095 if (ret) {
1096 goto end;
1097 }
1098
1099 if (event->event_class->context) {
1100 ret = bt_ctf_field_validate(event->context_payload);
1101 }
1102 end:
1103 return ret;
1104 }
1105
1106 BT_HIDDEN
1107 int bt_ctf_event_serialize(struct bt_ctf_event *event,
1108 struct ctf_stream_pos *pos)
1109 {
1110 int ret = 0;
1111
1112 assert(event);
1113 assert(pos);
1114 if (event->context_payload) {
1115 ret = bt_ctf_field_serialize(event->context_payload, pos);
1116 if (ret) {
1117 goto end;
1118 }
1119 }
1120
1121 if (event->fields_payload) {
1122 ret = bt_ctf_field_serialize(event->fields_payload, pos);
1123 if (ret) {
1124 goto end;
1125 }
1126 }
1127 end:
1128 return ret;
1129 }
1130
1131 BT_HIDDEN
1132 int bt_ctf_event_populate_event_header(struct bt_ctf_event *event)
1133 {
1134 int ret = 0;
1135 struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL;
1136
1137 if (!event) {
1138 ret = -1;
1139 goto end;
1140 }
1141
1142 id_field = bt_ctf_field_structure_get_field(event->event_header, "id");
1143 if (id_field) {
1144 ret = set_integer_field_value(id_field,
1145 (uint64_t) bt_ctf_event_class_get_id(
1146 event->event_class));
1147 if (ret) {
1148 goto end;
1149 }
1150 }
1151
1152 timestamp_field = bt_ctf_field_structure_get_field(event->event_header,
1153 "timestamp");
1154 if (timestamp_field) {
1155 struct bt_ctf_field_type *timestamp_field_type =
1156 bt_ctf_field_get_type(timestamp_field);
1157 struct bt_ctf_clock *mapped_clock;
1158
1159 assert(timestamp_field_type);
1160 mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
1161 timestamp_field_type);
1162 bt_ctf_field_type_put(timestamp_field_type);
1163 if (mapped_clock) {
1164 uint64_t timestamp = bt_ctf_clock_get_time(
1165 mapped_clock);
1166
1167 bt_ctf_clock_put(mapped_clock);
1168 if (timestamp == (uint64_t) -1ULL) {
1169 goto end;
1170 }
1171
1172 ret = set_integer_field_value(timestamp_field,
1173 timestamp);
1174 if (ret) {
1175 goto end;
1176 }
1177 }
1178 }
1179 end:
1180 if (id_field) {
1181 bt_ctf_field_put(id_field);
1182 }
1183 if (timestamp_field) {
1184 bt_ctf_field_put(timestamp_field);
1185 }
1186 return ret;
1187 }
This page took 0.051836 seconds and 5 git commands to generate.