3747a5cf9da21daad3f76ed2940ccf22a7bd437f
[babeltrace.git] / formats / ctf / ir / event-class.c
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>
41 #include <babeltrace/endian.h>
42
43 static
44 void bt_ctf_event_class_destroy(struct bt_object *obj);
45
46 struct 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
61 event_class->id = -1;
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
101 error:
102 BT_PUT(event_class);
103 BT_PUT(obj);
104 return event_class;
105 }
106
107 const 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
116 if (event_class->name) {
117 name = event_class->name;
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_value_string_get(obj, &name)) {
128 name = NULL;
129 }
130
131 end:
132 BT_PUT(obj);
133 return name;
134 }
135
136 int64_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
146 if (event_class->id >= 0) {
147 ret = event_class->id;
148 goto end;
149 }
150
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
167 end:
168 BT_PUT(obj);
169 return ret;
170 }
171
172 int 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
206 end:
207 BT_PUT(obj);
208 BT_PUT(stream_class);
209 return ret;
210 }
211
212 int 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
223 if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
224 !strcmp(name, "stream_id")) {
225 if (!bt_value_is_integer(value)) {
226 ret = -1;
227 goto end;
228 }
229 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
230 !strcmp(name, "loglevel_string")) {
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,
258 name, value);
259
260 end:
261 return ret;
262 }
263
264 int 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
276 end:
277 return ret;
278 }
279
280 const char *
281 bt_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
293 end:
294 return ret;
295 }
296
297 struct bt_value *
298 bt_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
310 end:
311 return ret;
312 }
313
314 struct bt_value *
315 bt_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
328 end:
329 return ret;
330
331 }
332
333 struct 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
339 struct 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;
350 end:
351 return payload;
352 }
353
354 int 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
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) {
366 ret = -1;
367 goto end;
368 }
369
370 bt_put(event_class->fields);
371 event_class->fields = bt_get(payload);
372 end:
373 return ret;
374 }
375
376 int 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);
396 end:
397 return ret;
398 }
399
400 int 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);
417 end:
418 return ret;
419 }
420
421 int 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);
440 end:
441 return ret;
442 }
443
444 struct 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);
470 end:
471 return field_type;
472 }
473
474 struct 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;
485 end:
486 return context_type;
487 }
488
489 int 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
495 if (!event_class || event_class->frozen) {
496 ret = -1;
497 goto end;
498 }
499
500 if (context && bt_ctf_field_type_get_type_id(context) !=
501 BT_CTF_TYPE_ID_STRUCT) {
502 ret = -1;
503 goto end;
504 }
505
506 bt_put(event_class->context);
507 event_class->context = bt_get(context);
508 end:
509 return ret;
510
511 }
512
513 void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
514 {
515 bt_get(event_class);
516 }
517
518 void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
519 {
520 bt_put(event_class);
521 }
522
523 BT_HIDDEN
524 int 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
544 end:
545 BT_PUT(obj);
546 return ret;
547 }
548
549 static
550 void 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
561 BT_HIDDEN
562 void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
563 {
564 assert(event_class);
565 event_class->frozen = 1;
566 event_class->name = bt_ctf_event_class_get_name(event_class);
567 event_class->id = bt_ctf_event_class_get_id(event_class);
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
573 BT_HIDDEN
574 int 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");
668 end:
669 context->current_indentation_level = 0;
670 BT_PUT(attr_value);
671 return ret;
672 }
673
674 void 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.04217 seconds and 3 git commands to generate.