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