ctf.fs: bt_ctf_notif_iter_create(): assert() that all medops exist
[babeltrace.git] / formats / ctf / ir / event-class.c
CommitLineData
272df73e
PP
1/*
2 * event-class.c
3 *
4 * Babeltrace CTF IR - Event class
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-class.h>
32#include <babeltrace/ctf-ir/event-class-internal.h>
33#include <babeltrace/ctf-ir/stream-class.h>
34#include <babeltrace/ctf-ir/stream-class-internal.h>
35#include <babeltrace/ctf-ir/trace-internal.h>
36#include <babeltrace/ctf-ir/validation-internal.h>
37#include <babeltrace/ctf-ir/utils.h>
38#include <babeltrace/ref.h>
39#include <babeltrace/ctf-ir/attributes-internal.h>
40#include <babeltrace/compiler.h>
6d9fe143 41#include <babeltrace/endian.h>
272df73e
PP
42
43static
44void bt_ctf_event_class_destroy(struct bt_object *obj);
45
46struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
47{
48 int ret;
49 struct bt_value *obj = NULL;
50 struct bt_ctf_event_class *event_class = NULL;
51
52 if (bt_ctf_validate_identifier(name)) {
53 goto error;
54 }
55
56 event_class = g_new0(struct bt_ctf_event_class, 1);
57 if (!event_class) {
58 goto error;
59 }
60
5990dd44 61 event_class->id = -1;
272df73e
PP
62 bt_object_init(event_class, bt_ctf_event_class_destroy);
63 event_class->fields = bt_ctf_field_type_structure_create();
64 if (!event_class->fields) {
65 goto error;
66 }
67
68 event_class->attributes = bt_ctf_attributes_create();
69 if (!event_class->attributes) {
70 goto error;
71 }
72
73 obj = bt_value_integer_create_init(-1);
74 if (!obj) {
75 goto error;
76 }
77
78 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
79 "id", obj);
80 if (ret) {
81 goto error;
82 }
83
84 BT_PUT(obj);
85
86 obj = bt_value_string_create_init(name);
87 if (!obj) {
88 goto error;
89 }
90
91 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
92 "name", obj);
93 if (ret) {
94 goto error;
95 }
96
97 BT_PUT(obj);
98
99 return event_class;
100
101error:
102 BT_PUT(event_class);
103 BT_PUT(obj);
104 return event_class;
105}
106
107const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
108{
109 struct bt_value *obj = NULL;
110 const char *name = NULL;
111
112 if (!event_class) {
113 goto end;
114 }
115
5990dd44
JG
116 if (event_class->name) {
117 name = event_class->name;
118 goto end;
119 }
120
272df73e
PP
121 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
122 BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
123 if (!obj) {
124 goto end;
125 }
126
127 if (bt_value_string_get(obj, &name)) {
128 name = NULL;
129 }
130
131end:
132 BT_PUT(obj);
133 return name;
134}
135
136int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
137{
138 struct bt_value *obj = NULL;
139 int64_t ret = 0;
140
141 if (!event_class) {
142 ret = -1;
143 goto end;
144 }
145
5990dd44
JG
146 if (event_class->id >= 0) {
147 ret = event_class->id;
148 goto end;
149 }
150
272df73e
PP
151 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
152 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
153 if (!obj) {
154 goto end;
155 }
156
157 if (bt_value_integer_get(obj, &ret)) {
158 ret = -1;
159 }
160
161 if (ret < 0) {
162 /* means ID is not set */
163 ret = -1;
164 goto end;
165 }
166
167end:
168 BT_PUT(obj);
169 return ret;
170}
171
172int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
173 uint32_t id)
174{
175 int ret = 0;
176 struct bt_value *obj = NULL;
177 struct bt_ctf_stream_class *stream_class = NULL;
178
179
180 if (!event_class) {
181 ret = -1;
182 goto end;
183 }
184
185 stream_class = bt_ctf_event_class_get_stream_class(event_class);
186 if (stream_class) {
187 /*
188 * We don't allow changing the id if the event class has already
189 * been added to a stream class.
190 */
191 ret = -1;
192 goto end;
193 }
194
195 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
196 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
197 if (!obj) {
198 goto end;
199 }
200
201 if (bt_value_integer_set(obj, id)) {
202 ret = -1;
203 goto end;
204 }
205
206end:
207 BT_PUT(obj);
208 BT_PUT(stream_class);
209 return ret;
210}
211
212int bt_ctf_event_class_set_attribute(
213 struct bt_ctf_event_class *event_class, const char *name,
214 struct bt_value *value)
215{
216 int ret = 0;
217
218 if (!event_class || !name || !value || event_class->frozen) {
219 ret = -1;
220 goto end;
221 }
222
2073703a
JG
223 if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
224 !strcmp(name, "stream_id")) {
272df73e
PP
225 if (!bt_value_is_integer(value)) {
226 ret = -1;
227 goto end;
228 }
c3c30b08
MD
229 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
230 !strcmp(name, "loglevel_string")) {
272df73e
PP
231 if (!bt_value_is_string(value)) {
232 ret = -1;
233 goto end;
234 }
235 } else {
236 /* unknown attribute */
237 ret = -1;
238 goto end;
239 }
240
241 /* "id" special case: >= 0 */
242 if (!strcmp(name, "id")) {
243 int64_t val;
244
245 ret = bt_value_integer_get(value, &val);
246
247 if (ret) {
248 goto end;
249 }
250
251 if (val < 0) {
252 ret = -1;
253 goto end;
254 }
255 }
256
257 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
2073703a 258 name, value);
272df73e
PP
259
260end:
261 return ret;
262}
263
264int bt_ctf_event_class_get_attribute_count(
265 struct bt_ctf_event_class *event_class)
266{
267 int ret = 0;
268
269 if (!event_class) {
270 ret = -1;
271 goto end;
272 }
273
274 ret = bt_ctf_attributes_get_count(event_class->attributes);
275
276end:
277 return ret;
278}
279
280const char *
281bt_ctf_event_class_get_attribute_name(
282 struct bt_ctf_event_class *event_class, int index)
283{
284 const char *ret;
285
286 if (!event_class) {
287 ret = NULL;
288 goto end;
289 }
290
291 ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
292
293end:
294 return ret;
295}
296
297struct bt_value *
298bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
299 int index)
300{
301 struct bt_value *ret;
302
303 if (!event_class) {
304 ret = NULL;
305 goto end;
306 }
307
308 ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
309
310end:
311 return ret;
312}
313
314struct bt_value *
315bt_ctf_event_class_get_attribute_value_by_name(
316 struct bt_ctf_event_class *event_class, const char *name)
317{
318 struct bt_value *ret;
319
320 if (!event_class || !name) {
321 ret = NULL;
322 goto end;
323 }
324
325 ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
326 name);
327
328end:
329 return ret;
330
331}
332
333struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
334 struct bt_ctf_event_class *event_class)
335{
336 return (struct bt_ctf_stream_class *) bt_object_get_parent(event_class);
337}
338
339struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
340 struct bt_ctf_event_class *event_class)
341{
342 struct bt_ctf_field_type *payload = NULL;
343
344 if (!event_class) {
345 goto end;
346 }
347
348 bt_get(event_class->fields);
349 payload = event_class->fields;
350end:
351 return payload;
352}
353
354int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
355 struct bt_ctf_field_type *payload)
356{
357 int ret = 0;
358
835b2d10
JG
359 if (!event_class) {
360 ret = -1;
361 goto end;
362 }
363
364 if (payload && bt_ctf_field_type_get_type_id(payload) !=
365 BT_CTF_TYPE_ID_STRUCT) {
272df73e
PP
366 ret = -1;
367 goto end;
368 }
369
272df73e 370 bt_put(event_class->fields);
835b2d10 371 event_class->fields = bt_get(payload);
272df73e
PP
372end:
373 return ret;
374}
375
376int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
377 struct bt_ctf_field_type *type,
378 const char *name)
379{
380 int ret = 0;
381
382 if (!event_class || !type || bt_ctf_validate_identifier(name) ||
383 event_class->frozen) {
384 ret = -1;
385 goto end;
386 }
387
388 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
389 BT_CTF_TYPE_ID_STRUCT) {
390 ret = -1;
391 goto end;
392 }
393
394 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
395 type, name);
396end:
397 return ret;
398}
399
400int bt_ctf_event_class_get_field_count(
401 struct bt_ctf_event_class *event_class)
402{
403 int ret;
404
405 if (!event_class) {
406 ret = -1;
407 goto end;
408 }
409
410 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
411 BT_CTF_TYPE_ID_STRUCT) {
412 ret = -1;
413 goto end;
414 }
415
416 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
417end:
418 return ret;
419}
420
421int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class,
422 const char **field_name, struct bt_ctf_field_type **field_type,
423 int index)
424{
425 int ret;
426
427 if (!event_class || index < 0) {
428 ret = -1;
429 goto end;
430 }
431
432 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
433 BT_CTF_TYPE_ID_STRUCT) {
434 ret = -1;
435 goto end;
436 }
437
438 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
439 field_name, field_type, index);
440end:
441 return ret;
442}
443
444struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
445 struct bt_ctf_event_class *event_class, const char *name)
446{
447 GQuark name_quark;
448 struct bt_ctf_field_type *field_type = NULL;
449
450 if (!event_class || !name) {
451 goto end;
452 }
453
454 if (bt_ctf_field_type_get_type_id(event_class->fields) !=
455 BT_CTF_TYPE_ID_STRUCT) {
456 goto end;
457 }
458
459 name_quark = g_quark_try_string(name);
460 if (!name_quark) {
461 goto end;
462 }
463
464 /*
465 * No need to increment field_type's reference count since getting it
466 * from the structure already does.
467 */
468 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
469 event_class->fields, name);
470end:
471 return field_type;
472}
473
474struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
475 struct bt_ctf_event_class *event_class)
476{
477 struct bt_ctf_field_type *context_type = NULL;
478
479 if (!event_class || !event_class->context) {
480 goto end;
481 }
482
483 bt_get(event_class->context);
484 context_type = event_class->context;
485end:
486 return context_type;
487}
488
489int bt_ctf_event_class_set_context_type(
490 struct bt_ctf_event_class *event_class,
491 struct bt_ctf_field_type *context)
492{
493 int ret = 0;
494
835b2d10 495 if (!event_class || event_class->frozen) {
272df73e
PP
496 ret = -1;
497 goto end;
498 }
499
835b2d10
JG
500 if (context && bt_ctf_field_type_get_type_id(context) !=
501 BT_CTF_TYPE_ID_STRUCT) {
272df73e
PP
502 ret = -1;
503 goto end;
504 }
505
272df73e 506 bt_put(event_class->context);
835b2d10 507 event_class->context = bt_get(context);
272df73e
PP
508end:
509 return ret;
510
511}
512
513void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
514{
515 bt_get(event_class);
516}
517
518void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
519{
520 bt_put(event_class);
521}
522
523BT_HIDDEN
524int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
525 uint32_t stream_id)
526{
527 int ret = 0;
528 struct bt_value *obj;
529
530 obj = bt_value_integer_create_init(stream_id);
531
532 if (!obj) {
533 ret = -1;
534 goto end;
535 }
536
537 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
538 "stream_id", obj);
539
540 if (event_class->frozen) {
541 bt_ctf_attributes_freeze(event_class->attributes);
542 }
543
544end:
545 BT_PUT(obj);
546 return ret;
547}
548
549static
550void bt_ctf_event_class_destroy(struct bt_object *obj)
551{
552 struct bt_ctf_event_class *event_class;
553
554 event_class = container_of(obj, struct bt_ctf_event_class, base);
555 bt_ctf_attributes_destroy(event_class->attributes);
556 bt_put(event_class->context);
557 bt_put(event_class->fields);
558 g_free(event_class);
559}
560
561BT_HIDDEN
562void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
563{
564 assert(event_class);
565 event_class->frozen = 1;
5990dd44
JG
566 event_class->name = bt_ctf_event_class_get_name(event_class);
567 event_class->id = bt_ctf_event_class_get_id(event_class);
272df73e
PP
568 bt_ctf_field_type_freeze(event_class->context);
569 bt_ctf_field_type_freeze(event_class->fields);
570 bt_ctf_attributes_freeze(event_class->attributes);
571}
572
573BT_HIDDEN
574int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
575 struct metadata_context *context)
576{
577 int i;
578 int count;
579 int ret = 0;
580 struct bt_value *attr_value = NULL;
581
582 assert(event_class);
583 assert(context);
584
585 context->current_indentation_level = 1;
586 g_string_assign(context->field_name, "");
587 g_string_append(context->string, "event {\n");
588 count = bt_ctf_event_class_get_attribute_count(event_class);
589
590 if (count < 0) {
591 ret = -1;
592 goto end;
593 }
594
595 for (i = 0; i < count; ++i) {
596 const char *attr_name = NULL;
597
598 attr_name = bt_ctf_event_class_get_attribute_name(
599 event_class, i);
600 attr_value = bt_ctf_event_class_get_attribute_value(
601 event_class, i);
602
603 if (!attr_name || !attr_value) {
604 ret = -1;
605 goto end;
606 }
607
608 switch (bt_value_get_type(attr_value)) {
609 case BT_VALUE_TYPE_INTEGER:
610 {
611 int64_t value;
612
613 ret = bt_value_integer_get(attr_value, &value);
614
615 if (ret) {
616 goto end;
617 }
618
619 g_string_append_printf(context->string,
620 "\t%s = %" PRId64 ";\n", attr_name, value);
621 break;
622 }
623
624 case BT_VALUE_TYPE_STRING:
625 {
626 const char *value;
627
628 ret = bt_value_string_get(attr_value, &value);
629
630 if (ret) {
631 goto end;
632 }
633
634 g_string_append_printf(context->string,
635 "\t%s = \"%s\";\n", attr_name, value);
636 break;
637 }
638
639 default:
640 /* should never happen */
641 assert(false);
642 break;
643 }
644
645 BT_PUT(attr_value);
646 }
647
648 if (event_class->context) {
649 g_string_append(context->string, "\tcontext := ");
650 ret = bt_ctf_field_type_serialize(event_class->context,
651 context);
652 if (ret) {
653 goto end;
654 }
655 g_string_append(context->string, ";\n");
656 }
657
658 if (event_class->fields) {
659 g_string_append(context->string, "\tfields := ");
660 ret = bt_ctf_field_type_serialize(event_class->fields, context);
661 if (ret) {
662 goto end;
663 }
664 g_string_append(context->string, ";\n");
665 }
666
667 g_string_append(context->string, "};\n\n");
668end:
669 context->current_indentation_level = 0;
670 BT_PUT(attr_value);
671 return ret;
672}
673
674void bt_ctf_event_class_set_native_byte_order(
675 struct bt_ctf_event_class *event_class,
676 int byte_order)
677{
678 if (!event_class) {
679 return;
680 }
681
682 assert(byte_order == 0 || byte_order == LITTLE_ENDIAN ||
683 byte_order == BIG_ENDIAN);
684
685 bt_ctf_field_type_set_native_byte_order(event_class->context,
686 byte_order);
687 bt_ctf_field_type_set_native_byte_order(event_class->fields,
688 byte_order);
689}
This page took 0.053507 seconds and 4 git commands to generate.