ir: do not create empty structure for optional scope field types
[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 #define BT_LOG_TAG "EVENT-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/ctf-ir/fields-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/event-class.h>
35 #include <babeltrace/ctf-ir/event-class-internal.h>
36 #include <babeltrace/ctf-ir/stream-class.h>
37 #include <babeltrace/ctf-ir/stream-class-internal.h>
38 #include <babeltrace/ctf-ir/trace-internal.h>
39 #include <babeltrace/ctf-ir/validation-internal.h>
40 #include <babeltrace/ctf-ir/utils.h>
41 #include <babeltrace/ref.h>
42 #include <babeltrace/ctf-ir/attributes-internal.h>
43 #include <babeltrace/compiler-internal.h>
44 #include <babeltrace/endian-internal.h>
45 #include <babeltrace/types.h>
46 #include <babeltrace/values-internal.h>
47 #include <inttypes.h>
48 #include <stdlib.h>
49
50 static
51 void bt_ctf_event_class_destroy(struct bt_object *obj);
52
53 struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
54 {
55 int ret;
56 struct bt_value *obj = NULL;
57 struct bt_ctf_event_class *event_class = NULL;
58
59 BT_LOGD("Creating event class object: name=\"%s\"",
60 name);
61
62 if (bt_ctf_validate_identifier(name)) {
63 BT_LOGW("Invalid parameter: event class's name is not a valid CTF identifier: "
64 "name=\"%s\"", name);
65 goto error;
66 }
67
68 event_class = g_new0(struct bt_ctf_event_class, 1);
69 if (!event_class) {
70 BT_LOGE_STR("Failed to allocate one event class.");
71 goto error;
72 }
73
74 event_class->id = -1;
75 bt_object_init(event_class, bt_ctf_event_class_destroy);
76 event_class->fields = bt_ctf_field_type_structure_create();
77 if (!event_class->fields) {
78 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
79 goto error;
80 }
81
82 event_class->attributes = bt_ctf_attributes_create();
83 if (!event_class->attributes) {
84 BT_LOGE_STR("Cannot create event class's attributes object.");
85 goto error;
86 }
87
88 obj = bt_value_integer_create_init(-1);
89 if (!obj) {
90 BT_LOGE_STR("Cannot create integer value object.");
91 goto error;
92 }
93
94 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
95 "id", obj);
96 if (ret) {
97 BT_LOGE("Cannot set event class's attributes's `id` field: ret=%d",
98 ret);
99 goto error;
100 }
101
102 BT_PUT(obj);
103
104 obj = bt_value_string_create_init(name);
105 if (!obj) {
106 BT_LOGE_STR("Cannot create string value object.");
107 goto error;
108 }
109
110 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
111 "name", obj);
112 if (ret) {
113 BT_LOGE("Cannot set event class's attributes's `name` field: ret=%d",
114 ret);
115 goto error;
116 }
117
118 BT_PUT(obj);
119 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
120 event_class, bt_ctf_event_class_get_name(event_class));
121 return event_class;
122
123 error:
124 BT_PUT(event_class);
125 BT_PUT(obj);
126 return event_class;
127 }
128
129 const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
130 {
131 struct bt_value *obj = NULL;
132 const char *name = NULL;
133 int ret;
134
135 if (!event_class) {
136 BT_LOGW_STR("Invalid parameter: event class is NULL.");
137 goto end;
138 }
139
140 if (event_class->name) {
141 name = event_class->name;
142 goto end;
143 }
144
145 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
146 BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
147 assert(obj);
148 ret = bt_value_string_get(obj, &name);
149 assert(ret == 0);
150
151 end:
152 BT_PUT(obj);
153 return name;
154 }
155
156 int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
157 {
158 struct bt_value *obj = NULL;
159 int64_t ret = 0;
160 int int_ret;
161
162 if (!event_class) {
163 BT_LOGW_STR("Invalid parameter: event class is NULL.");
164 ret = (int64_t) -1;
165 goto end;
166 }
167
168 if (event_class->id >= 0) {
169 ret = (int64_t) event_class->id;
170 goto end;
171 }
172
173 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
174 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
175 assert(obj);
176 int_ret = bt_value_integer_get(obj, &ret);
177 assert(int_ret == 0);
178 if (ret < 0) {
179 /* means ID is not set */
180 BT_LOGV("Event class's ID is not set: addr=%p, name=\"%s\"",
181 event_class, bt_ctf_event_class_get_name(event_class));
182 ret = (int64_t) -1;
183 goto end;
184 }
185
186 end:
187 BT_PUT(obj);
188 return ret;
189 }
190
191 int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
192 uint64_t id_param)
193 {
194 int ret = 0;
195 struct bt_value *obj = NULL;
196 int64_t id = (int64_t) id_param;
197
198 if (!event_class) {
199 BT_LOGW_STR("Invalid parameter: event class is NULL.");
200 ret = -1;
201 goto end;
202 }
203
204 if (event_class->frozen) {
205 BT_LOGW("Invalid parameter: event class is frozen: "
206 "addr=%p, name=\"%s\", id=%" PRId64,
207 event_class, bt_ctf_event_class_get_name(event_class),
208 bt_ctf_event_class_get_id(event_class));
209 ret = -1;
210 goto end;
211 }
212
213 if (id < 0) {
214 BT_LOGW("Invalid parameter: invalid event class's ID: "
215 "addr=%p, name=\"%s\", id=%" PRIu64,
216 event_class, bt_ctf_event_class_get_name(event_class),
217 id_param);
218 ret = -1;
219 goto end;
220 }
221
222 obj = bt_ctf_attributes_get_field_value(event_class->attributes,
223 BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
224 assert(obj);
225 ret = bt_value_integer_set(obj, id);
226 assert(ret == 0);
227 BT_LOGV("Set event class's ID: "
228 "addr=%p, name=\"%s\", id=%" PRId64,
229 event_class, bt_ctf_event_class_get_name(event_class), id);
230
231 end:
232 BT_PUT(obj);
233 return ret;
234 }
235
236 int bt_ctf_event_class_set_attribute(
237 struct bt_ctf_event_class *event_class, const char *name,
238 struct bt_value *value)
239 {
240 int ret = 0;
241
242 if (!event_class || !name || !value) {
243 BT_LOGW("Invalid parameter: event class, name, or value is NULL: "
244 "event-class-addr=%p, name-addr=%p, value-addr=%p",
245 event_class, name, value);
246 ret = -1;
247 goto end;
248 }
249
250 if (event_class->frozen) {
251 BT_LOGW("Invalid parameter: event class is frozen: "
252 "addr=%p, name=\"%s\", id=%" PRId64 ", attr-name=\"%s\"",
253 event_class, bt_ctf_event_class_get_name(event_class),
254 bt_ctf_event_class_get_id(event_class), name);
255 ret = -1;
256 goto end;
257 }
258
259 if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
260 !strcmp(name, "stream_id")) {
261 if (!bt_value_is_integer(value)) {
262 BT_LOGW("Invalid parameter: this event class's attribute must have an integer value: "
263 "event-class-addr=%p, event-class-name=\"%s\", "
264 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
265 "attr-type=%s", event_class,
266 bt_ctf_event_class_get_name(event_class),
267 bt_ctf_event_class_get_id(event_class), name,
268 bt_value_type_string(bt_value_get_type(value)));
269 ret = -1;
270 goto end;
271 }
272 } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
273 !strcmp(name, "loglevel_string")) {
274 if (!bt_value_is_string(value)) {
275 BT_LOGW("Invalid parameter: this event class's attribute must have a string value: "
276 "event-class-addr=%p, event-class-name=\"%s\", "
277 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
278 "attr-type=%s", event_class,
279 bt_ctf_event_class_get_name(event_class),
280 bt_ctf_event_class_get_id(event_class), name,
281 bt_value_type_string(bt_value_get_type(value)));
282 ret = -1;
283 goto end;
284 }
285 } else {
286 /* unknown attribute */
287 BT_LOGW("Invalid parameter: unknown event class's attribute name: "
288 "event-class-addr=%p, event-class-name=\"%s\", "
289 "event-class-id=%" PRId64 ", attr-name=\"%s\"",
290 event_class, bt_ctf_event_class_get_name(event_class),
291 bt_ctf_event_class_get_id(event_class), name);
292 ret = -1;
293 goto end;
294 }
295
296 /* "id" special case: >= 0 */
297 if (!strcmp(name, "id")) {
298 int64_t val;
299
300 ret = bt_value_integer_get(value, &val);
301 assert(ret == 0);
302 BT_LOGV("Setting event's ID: id=%" PRId64, val);
303 ret = bt_ctf_event_class_set_id(event_class, (uint64_t) val);
304 if (ret) {
305 goto end;
306 }
307 }
308
309 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
310 name, value);
311 assert(ret == 0);
312
313 if (BT_LOG_ON_VERBOSE) {
314 if (bt_value_is_integer(value)) {
315 int64_t val;
316
317 ret = bt_value_integer_get(value, &val);
318 assert(ret == 0);
319 BT_LOGV("Set event class's integer attribute: "
320 "event-class-addr=%p, event-class-name=\"%s\", "
321 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
322 "attr-value=%" PRId64,
323 event_class, bt_ctf_event_class_get_name(event_class),
324 bt_ctf_event_class_get_id(event_class), name,
325 val);
326 } else if (bt_value_is_string(value)) {
327 const char *val;
328
329 ret = bt_value_string_get(value, &val);
330 assert(ret == 0);
331 BT_LOGV("Set event class's string attribute: "
332 "event-class-addr=%p, event-class-name=\"%s\", "
333 "event-class-id=%" PRId64 ", attr-name=\"%s\", "
334 "attr-value=\"%s\"",
335 event_class, bt_ctf_event_class_get_name(event_class),
336 bt_ctf_event_class_get_id(event_class), name,
337 val);
338 }
339 }
340
341 end:
342 return ret;
343 }
344
345 int64_t bt_ctf_event_class_get_attribute_count(
346 struct bt_ctf_event_class *event_class)
347 {
348 int64_t ret;
349
350 if (!event_class) {
351 BT_LOGW_STR("Invalid parameter: event class is NULL.");
352 ret = (int64_t) -1;
353 goto end;
354 }
355
356 ret = bt_ctf_attributes_get_count(event_class->attributes);
357 assert(ret >= 0);
358
359 end:
360 return ret;
361 }
362
363 const char *
364 bt_ctf_event_class_get_attribute_name_by_index(
365 struct bt_ctf_event_class *event_class, uint64_t index)
366 {
367 const char *ret;
368
369 if (!event_class) {
370 BT_LOGW_STR("Invalid parameter: event class is NULL.");
371 ret = NULL;
372 goto end;
373 }
374
375 ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
376 if (!ret) {
377 BT_LOGW("Cannot get event class's attribute name by index: "
378 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
379 event_class, bt_ctf_event_class_get_name(event_class),
380 bt_ctf_event_class_get_id(event_class), index);
381 }
382
383 end:
384 return ret;
385 }
386
387 struct bt_value *
388 bt_ctf_event_class_get_attribute_value_by_index(
389 struct bt_ctf_event_class *event_class, uint64_t index)
390 {
391 struct bt_value *ret;
392
393 if (!event_class) {
394 BT_LOGW_STR("Invalid parameter: event class is NULL.");
395 ret = NULL;
396 goto end;
397 }
398
399 ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
400 if (!ret) {
401 BT_LOGW("Cannot get event class's attribute value by index: "
402 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
403 event_class, bt_ctf_event_class_get_name(event_class),
404 bt_ctf_event_class_get_id(event_class), index);
405 }
406
407 end:
408 return ret;
409 }
410
411 struct bt_value *
412 bt_ctf_event_class_get_attribute_value_by_name(
413 struct bt_ctf_event_class *event_class, const char *name)
414 {
415 struct bt_value *ret;
416
417 if (!event_class || !name) {
418 BT_LOGW("Invalid parameter: event class or name is NULL: "
419 "event-class-addr=%p, name-addr=%p",
420 event_class, name);
421 ret = NULL;
422 goto end;
423 }
424
425 ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
426 name);
427 if (!ret) {
428 BT_LOGV("Cannot find event class's attribute: "
429 "addr=%p, event-class-name=\"%s\", id=%" PRId64 ", "
430 "attr-name=\"%s\"",
431 event_class, bt_ctf_event_class_get_name(event_class),
432 bt_ctf_event_class_get_id(event_class), name);
433 }
434
435 end:
436 return ret;
437
438 }
439
440 struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
441 struct bt_ctf_event_class *event_class)
442 {
443 return event_class ?
444 bt_get(bt_ctf_event_class_borrow_stream_class(event_class)) :
445 NULL;
446 }
447
448 struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
449 struct bt_ctf_event_class *event_class)
450 {
451 struct bt_ctf_field_type *payload = NULL;
452
453 if (!event_class) {
454 BT_LOGW_STR("Invalid parameter: event class is NULL.");
455 goto end;
456 }
457
458 bt_get(event_class->fields);
459 payload = event_class->fields;
460 end:
461 return payload;
462 }
463
464 int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
465 struct bt_ctf_field_type *payload)
466 {
467 int ret = 0;
468
469 if (!event_class) {
470 BT_LOGW_STR("Invalid parameter: event class is NULL.");
471 ret = -1;
472 goto end;
473 }
474
475 if (payload && bt_ctf_field_type_get_type_id(payload) !=
476 BT_CTF_FIELD_TYPE_ID_STRUCT) {
477 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
478 "addr=%p, name=\"%s\", id=%" PRId64 ", "
479 "payload-ft-addr=%p, payload-ft-id=%s",
480 event_class, bt_ctf_event_class_get_name(event_class),
481 bt_ctf_event_class_get_id(event_class), payload,
482 bt_ctf_field_type_id_string(
483 bt_ctf_field_type_get_type_id(payload)));
484 ret = -1;
485 goto end;
486 }
487
488 bt_put(event_class->fields);
489 event_class->fields = bt_get(payload);
490 BT_LOGV("Set event class's payload field type: "
491 "event-class-addr=%p, event-class-name=\"%s\", "
492 "event-class-id=%" PRId64 ", payload-ft-addr=%p",
493 event_class, bt_ctf_event_class_get_name(event_class),
494 bt_ctf_event_class_get_id(event_class), payload);
495 end:
496 return ret;
497 }
498
499 int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
500 struct bt_ctf_field_type *type,
501 const char *name)
502 {
503 int ret = 0;
504
505 if (!event_class || !type) {
506 BT_LOGW("Invalid parameter: event class or field type is NULL: "
507 "event-class-addr=%p, field-type-addr=%p",
508 event_class, type);
509 ret = -1;
510 goto end;
511 }
512
513 if (bt_ctf_validate_identifier(name)) {
514 BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
515 "addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"",
516 event_class, bt_ctf_event_class_get_name(event_class),
517 bt_ctf_event_class_get_id(event_class),
518 name);
519 ret = -1;
520 goto end;
521 }
522
523 if (event_class->frozen) {
524 BT_LOGW("Invalid parameter: event class is frozen: "
525 "addr=%p, name=\"%s\", id=%" PRId64,
526 event_class, bt_ctf_event_class_get_name(event_class),
527 bt_ctf_event_class_get_id(event_class));
528 ret = -1;
529 goto end;
530 }
531
532 if (!event_class->fields) {
533 BT_LOGW("Event class has no payload field type: "
534 "addr=%p, name=\"%s\", id=%" PRId64,
535 event_class, bt_ctf_event_class_get_name(event_class),
536 bt_ctf_event_class_get_id(event_class));
537 ret = -1;
538 goto end;
539 }
540
541 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
542 BT_CTF_FIELD_TYPE_ID_STRUCT);
543 ret = bt_ctf_field_type_structure_add_field(event_class->fields,
544 type, name);
545 BT_LOGV("Added field to event class's payload field type: "
546 "event-class-addr=%p, event-class-name=\"%s\", "
547 "event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p",
548 event_class, bt_ctf_event_class_get_name(event_class),
549 bt_ctf_event_class_get_id(event_class), name, type);
550 end:
551 return ret;
552 }
553
554 int64_t bt_ctf_event_class_get_payload_type_field_count(
555 struct bt_ctf_event_class *event_class)
556 {
557 int64_t ret;
558
559 if (!event_class) {
560 BT_LOGW_STR("Invalid parameter: event class is NULL.");
561 ret = (int64_t) -1;
562 goto end;
563 }
564
565 if (!event_class->fields) {
566 BT_LOGV("Event class has no payload field type: "
567 "addr=%p, name=\"%s\", id=%" PRId64,
568 event_class, bt_ctf_event_class_get_name(event_class),
569 bt_ctf_event_class_get_id(event_class));
570 ret = (int64_t) -1;
571 goto end;
572 }
573
574 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
575 BT_CTF_FIELD_TYPE_ID_STRUCT);
576 ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
577 end:
578 return ret;
579 }
580
581 int bt_ctf_event_class_get_payload_type_field_by_index(
582 struct bt_ctf_event_class *event_class,
583 const char **field_name, struct bt_ctf_field_type **field_type,
584 uint64_t index)
585 {
586 int ret;
587
588 if (!event_class) {
589 BT_LOGW_STR("Invalid parameter: event class is NULL.");
590 ret = -1;
591 goto end;
592 }
593
594 if (!event_class->fields) {
595 BT_LOGV("Event class has no payload field type: "
596 "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64,
597 event_class, bt_ctf_event_class_get_name(event_class),
598 bt_ctf_event_class_get_id(event_class), index);
599 ret = -1;
600 goto end;
601 }
602
603 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
604 BT_CTF_FIELD_TYPE_ID_STRUCT);
605 ret = bt_ctf_field_type_structure_get_field(event_class->fields,
606 field_name, field_type, index);
607 end:
608 return ret;
609 }
610
611 struct bt_ctf_field_type *
612 bt_ctf_event_class_get_payload_type_field_type_by_name(
613 struct bt_ctf_event_class *event_class, const char *name)
614 {
615 GQuark name_quark;
616 struct bt_ctf_field_type *field_type = NULL;
617
618 if (!event_class || !name) {
619 BT_LOGW("Invalid parameter: event class or name is NULL: "
620 "event-class-addr=%p, name-addr=%p",
621 event_class, name);
622 goto end;
623 }
624
625 if (!event_class->fields) {
626 BT_LOGV("Event class has no payload field type: "
627 "addr=%p, name=\"%s\", id=%" PRId64,
628 event_class, bt_ctf_event_class_get_name(event_class),
629 bt_ctf_event_class_get_id(event_class));
630 goto end;
631 }
632
633 assert(bt_ctf_field_type_get_type_id(event_class->fields) ==
634 BT_CTF_FIELD_TYPE_ID_STRUCT);
635 name_quark = g_quark_try_string(name);
636 if (!name_quark) {
637 BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
638 goto end;
639 }
640
641 /*
642 * No need to increment field_type's reference count since getting it
643 * from the structure already does.
644 */
645 field_type = bt_ctf_field_type_structure_get_field_type_by_name(
646 event_class->fields, name);
647 end:
648 return field_type;
649 }
650
651 struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
652 struct bt_ctf_event_class *event_class)
653 {
654 struct bt_ctf_field_type *context_type = NULL;
655
656 if (!event_class) {
657 BT_LOGW_STR("Invalid parameter: event class is NULL.");
658 goto end;
659 }
660
661 if (!event_class->context) {
662 BT_LOGV("Event class has no context field type: "
663 "addr=%p, name=\"%s\", id=%" PRId64,
664 event_class, bt_ctf_event_class_get_name(event_class),
665 bt_ctf_event_class_get_id(event_class));
666 goto end;
667 }
668
669 bt_get(event_class->context);
670 context_type = event_class->context;
671 end:
672 return context_type;
673 }
674
675 int bt_ctf_event_class_set_context_type(
676 struct bt_ctf_event_class *event_class,
677 struct bt_ctf_field_type *context)
678 {
679 int ret = 0;
680
681 if (!event_class) {
682 BT_LOGW_STR("Invalid parameter: event class is NULL.");
683 ret = -1;
684 goto end;
685 }
686
687 if (event_class->frozen) {
688 BT_LOGW("Invalid parameter: event class is frozen: "
689 "addr=%p, name=\"%s\", id=%" PRId64,
690 event_class, bt_ctf_event_class_get_name(event_class),
691 bt_ctf_event_class_get_id(event_class));
692 ret = -1;
693 goto end;
694 }
695
696 if (context && bt_ctf_field_type_get_type_id(context) !=
697 BT_CTF_FIELD_TYPE_ID_STRUCT) {
698 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
699 "addr=%p, name=\"%s\", id=%" PRId64 ", "
700 "context-ft-id=%s",
701 event_class, bt_ctf_event_class_get_name(event_class),
702 bt_ctf_event_class_get_id(event_class),
703 bt_ctf_field_type_id_string(
704 bt_ctf_field_type_get_type_id(context)));
705 ret = -1;
706 goto end;
707 }
708
709 bt_put(event_class->context);
710 event_class->context = bt_get(context);
711 BT_LOGV("Set event class's context field type: "
712 "event-class-addr=%p, event-class-name=\"%s\", "
713 "event-class-id=%" PRId64 ", context-ft-addr=%p",
714 event_class, bt_ctf_event_class_get_name(event_class),
715 bt_ctf_event_class_get_id(event_class), context);
716 end:
717 return ret;
718
719 }
720
721 /* Pre-2.0 CTF writer backward compatibility */
722 void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
723 {
724 bt_get(event_class);
725 }
726
727 /* Pre-2.0 CTF writer backward compatibility */
728 void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
729 {
730 bt_put(event_class);
731 }
732
733 BT_HIDDEN
734 int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
735 uint64_t stream_id_param)
736 {
737 int ret = 0;
738 struct bt_value *obj = NULL;
739 int64_t stream_id = (int64_t) stream_id_param;
740
741 assert(event_class);
742 assert(stream_id >= 0);
743 obj = bt_value_integer_create_init(stream_id);
744 if (!obj) {
745 BT_LOGE_STR("Cannot create integer value object.");
746 ret = -1;
747 goto end;
748 }
749
750 ret = bt_ctf_attributes_set_field_value(event_class->attributes,
751 "stream_id", obj);
752 if (ret) {
753 BT_LOGE("Cannot set event class's attributes's `stream_id` field: "
754 "addr=%p, name=\"%s\", id=%" PRId64 ", ret=%d",
755 event_class, bt_ctf_event_class_get_name(event_class),
756 bt_ctf_event_class_get_id(event_class), ret);
757 goto end;
758 }
759
760 if (event_class->frozen) {
761 BT_LOGV_STR("Freezing event class's attributes because event class is frozen.");
762 bt_ctf_attributes_freeze(event_class->attributes);
763 }
764
765 BT_LOGV("Set event class's stream class ID: "
766 "event-class-addr=%p, event-class-name=\"%s\", "
767 "event-class-id=%" PRId64 ", stream-class-id=%" PRId64,
768 event_class, bt_ctf_event_class_get_name(event_class),
769 bt_ctf_event_class_get_id(event_class), stream_id);
770
771 end:
772 BT_PUT(obj);
773 return ret;
774 }
775
776 static
777 void bt_ctf_event_class_destroy(struct bt_object *obj)
778 {
779 struct bt_ctf_event_class *event_class;
780
781 event_class = container_of(obj, struct bt_ctf_event_class, base);
782 BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64,
783 event_class, bt_ctf_event_class_get_name(event_class),
784 bt_ctf_event_class_get_id(event_class));
785 BT_LOGD_STR("Destroying event class's attributes.");
786 bt_ctf_attributes_destroy(event_class->attributes);
787 BT_LOGD_STR("Putting context field type.");
788 bt_put(event_class->context);
789 BT_LOGD_STR("Putting payload field type.");
790 bt_put(event_class->fields);
791 g_free(event_class);
792 }
793
794 BT_HIDDEN
795 void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
796 {
797 assert(event_class);
798
799 if (event_class->frozen) {
800 return;
801 }
802
803 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64,
804 event_class, bt_ctf_event_class_get_name(event_class),
805 bt_ctf_event_class_get_id(event_class));
806 event_class->frozen = 1;
807 event_class->name = bt_ctf_event_class_get_name(event_class);
808 event_class->id = bt_ctf_event_class_get_id(event_class);
809 BT_LOGD_STR("Freezing event class's context field type.");
810 bt_ctf_field_type_freeze(event_class->context);
811 BT_LOGD_STR("Freezing event class's payload field type.");
812 bt_ctf_field_type_freeze(event_class->fields);
813 BT_LOGD_STR("Freezing event class's attributes.");
814 bt_ctf_attributes_freeze(event_class->attributes);
815 }
816
817 BT_HIDDEN
818 int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
819 struct metadata_context *context)
820 {
821 int64_t i;
822 int64_t count;
823 int ret = 0;
824 struct bt_value *attr_value = NULL;
825
826 assert(event_class);
827 assert(context);
828 BT_LOGD("Serializing event class's metadata: "
829 "event-class-addr=%p, event-class-name=\"%s\", "
830 "event-class-id=%" PRId64 ", metadata-context-addr=%p",
831 event_class, bt_ctf_event_class_get_name(event_class),
832 bt_ctf_event_class_get_id(event_class), context);
833 context->current_indentation_level = 1;
834 g_string_assign(context->field_name, "");
835 g_string_append(context->string, "event {\n");
836 count = bt_ctf_event_class_get_attribute_count(event_class);
837 assert(count >= 0);
838
839 for (i = 0; i < count; ++i) {
840 const char *attr_name = NULL;
841
842 attr_name = bt_ctf_event_class_get_attribute_name_by_index(
843 event_class, i);
844 assert(attr_name);
845 attr_value = bt_ctf_event_class_get_attribute_value_by_index(
846 event_class, i);
847 assert(attr_value);
848
849 switch (bt_value_get_type(attr_value)) {
850 case BT_VALUE_TYPE_INTEGER:
851 {
852 int64_t value;
853
854 ret = bt_value_integer_get(attr_value, &value);
855 assert(ret == 0);
856 g_string_append_printf(context->string,
857 "\t%s = %" PRId64 ";\n", attr_name, value);
858 break;
859 }
860
861 case BT_VALUE_TYPE_STRING:
862 {
863 const char *value;
864
865 ret = bt_value_string_get(attr_value, &value);
866 assert(ret == 0);
867 g_string_append_printf(context->string,
868 "\t%s = \"%s\";\n", attr_name, value);
869 break;
870 }
871
872 default:
873 /* should never happen */
874 abort();
875 break;
876 }
877
878 BT_PUT(attr_value);
879 }
880
881 if (event_class->context) {
882 g_string_append(context->string, "\tcontext := ");
883 BT_LOGD_STR("Serializing event class's context field type metadata.");
884 ret = bt_ctf_field_type_serialize(event_class->context,
885 context);
886 if (ret) {
887 BT_LOGW("Cannot serialize event class's context field type's metadata: "
888 "ret=%d", ret);
889 goto end;
890 }
891 g_string_append(context->string, ";\n");
892 }
893
894 if (event_class->fields) {
895 g_string_append(context->string, "\tfields := ");
896 BT_LOGD_STR("Serializing event class's payload field type metadata.");
897 ret = bt_ctf_field_type_serialize(event_class->fields, context);
898 if (ret) {
899 BT_LOGW("Cannot serialize event class's payload field type's metadata: "
900 "ret=%d", ret);
901 goto end;
902 }
903 g_string_append(context->string, ";\n");
904 }
905
906 g_string_append(context->string, "};\n\n");
907 end:
908 context->current_indentation_level = 0;
909 BT_PUT(attr_value);
910 return ret;
911 }
This page took 0.047791 seconds and 5 git commands to generate.