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