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