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 | 62 | if (bt_ctf_validate_identifier(name)) { |
f8b979f9 PP |
63 | BT_LOGW("Invalid parameter: event class's name is not a valid CTF identifier: " |
64 | "name=\"%s\"", name); | |
272df73e PP |
65 | goto error; |
66 | } | |
67 | ||
68 | event_class = g_new0(struct bt_ctf_event_class, 1); | |
69 | if (!event_class) { | |
f8b979f9 | 70 | BT_LOGE_STR("Failed to allocate one event class."); |
272df73e PP |
71 | goto error; |
72 | } | |
73 | ||
5990dd44 | 74 | event_class->id = -1; |
272df73e PP |
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) { | |
f8b979f9 | 78 | BT_LOGE_STR("Cannot create event class's initial payload field type object."); |
272df73e PP |
79 | goto error; |
80 | } | |
81 | ||
82 | event_class->attributes = bt_ctf_attributes_create(); | |
83 | if (!event_class->attributes) { | |
f8b979f9 | 84 | BT_LOGE_STR("Cannot create event class's attributes object."); |
272df73e PP |
85 | goto error; |
86 | } | |
87 | ||
88 | obj = bt_value_integer_create_init(-1); | |
89 | if (!obj) { | |
f8b979f9 | 90 | BT_LOGE_STR("Cannot create integer value object."); |
272df73e PP |
91 | goto error; |
92 | } | |
93 | ||
94 | ret = bt_ctf_attributes_set_field_value(event_class->attributes, | |
95 | "id", obj); | |
96 | if (ret) { | |
f8b979f9 PP |
97 | BT_LOGE("Cannot set event class's attributes's `id` field: ret=%d", |
98 | ret); | |
272df73e PP |
99 | goto error; |
100 | } | |
101 | ||
102 | BT_PUT(obj); | |
103 | ||
104 | obj = bt_value_string_create_init(name); | |
105 | if (!obj) { | |
f8b979f9 | 106 | BT_LOGE_STR("Cannot create string value object."); |
272df73e PP |
107 | goto error; |
108 | } | |
109 | ||
110 | ret = bt_ctf_attributes_set_field_value(event_class->attributes, | |
111 | "name", obj); | |
112 | if (ret) { | |
f8b979f9 PP |
113 | BT_LOGE("Cannot set event class's attributes's `name` field: ret=%d", |
114 | ret); | |
272df73e PP |
115 | goto error; |
116 | } | |
117 | ||
118 | BT_PUT(obj); | |
f8b979f9 PP |
119 | BT_LOGD("Created event class object: addr=%p, name=\"%s\"", |
120 | event_class, bt_ctf_event_class_get_name(event_class)); | |
272df73e PP |
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; | |
f8b979f9 | 133 | int ret; |
272df73e PP |
134 | |
135 | if (!event_class) { | |
f8b979f9 | 136 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
137 | goto end; |
138 | } | |
139 | ||
5990dd44 JG |
140 | if (event_class->name) { |
141 | name = event_class->name; | |
142 | goto end; | |
143 | } | |
144 | ||
272df73e PP |
145 | obj = bt_ctf_attributes_get_field_value(event_class->attributes, |
146 | BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX); | |
f8b979f9 PP |
147 | assert(obj); |
148 | ret = bt_value_string_get(obj, &name); | |
149 | assert(ret == 0); | |
272df73e PP |
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; | |
f8b979f9 | 160 | int int_ret; |
272df73e PP |
161 | |
162 | if (!event_class) { | |
f8b979f9 | 163 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9ac68eb1 | 164 | ret = (int64_t) -1; |
272df73e PP |
165 | goto end; |
166 | } | |
167 | ||
5990dd44 | 168 | if (event_class->id >= 0) { |
9ac68eb1 | 169 | ret = (int64_t) event_class->id; |
5990dd44 JG |
170 | goto end; |
171 | } | |
172 | ||
272df73e PP |
173 | obj = bt_ctf_attributes_get_field_value(event_class->attributes, |
174 | BT_CTF_EVENT_CLASS_ATTR_ID_INDEX); | |
f8b979f9 PP |
175 | assert(obj); |
176 | int_ret = bt_value_integer_get(obj, &ret); | |
177 | assert(int_ret == 0); | |
272df73e PP |
178 | if (ret < 0) { |
179 | /* means ID is not set */ | |
f8b979f9 PP |
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)); | |
9ac68eb1 | 182 | ret = (int64_t) -1; |
272df73e PP |
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, | |
9ac68eb1 | 192 | uint64_t id_param) |
272df73e PP |
193 | { |
194 | int ret = 0; | |
195 | struct bt_value *obj = NULL; | |
9ac68eb1 | 196 | int64_t id = (int64_t) id_param; |
272df73e | 197 | |
f8b979f9 PP |
198 | if (!event_class) { |
199 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
272df73e PP |
200 | ret = -1; |
201 | goto end; | |
202 | } | |
203 | ||
f8b979f9 PP |
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)); | |
272df73e PP |
209 | ret = -1; |
210 | goto end; | |
211 | } | |
212 | ||
f8b979f9 PP |
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); | |
272df73e PP |
218 | ret = -1; |
219 | goto end; | |
220 | } | |
221 | ||
f8b979f9 PP |
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 | ||
272df73e PP |
231 | end: |
232 | BT_PUT(obj); | |
272df73e PP |
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 | ||
f8b979f9 PP |
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); | |
272df73e PP |
255 | ret = -1; |
256 | goto end; | |
257 | } | |
258 | ||
2073703a JG |
259 | if (!strcmp(name, "id") || !strcmp(name, "loglevel") || |
260 | !strcmp(name, "stream_id")) { | |
272df73e | 261 | if (!bt_value_is_integer(value)) { |
f8b979f9 PP |
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))); | |
272df73e PP |
269 | ret = -1; |
270 | goto end; | |
271 | } | |
c3c30b08 MD |
272 | } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") || |
273 | !strcmp(name, "loglevel_string")) { | |
272df73e | 274 | if (!bt_value_is_string(value)) { |
f8b979f9 PP |
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))); | |
272df73e PP |
282 | ret = -1; |
283 | goto end; | |
284 | } | |
285 | } else { | |
286 | /* unknown attribute */ | |
f8b979f9 PP |
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); | |
272df73e PP |
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); | |
f8b979f9 | 301 | assert(ret == 0); |
0352f8fa | 302 | BT_LOGV("Setting event's ID: id=%" PRId64, val); |
f8b979f9 | 303 | ret = bt_ctf_event_class_set_id(event_class, (uint64_t) val); |
272df73e PP |
304 | if (ret) { |
305 | goto end; | |
306 | } | |
272df73e PP |
307 | } |
308 | ||
309 | ret = bt_ctf_attributes_set_field_value(event_class->attributes, | |
2073703a | 310 | name, value); |
f8b979f9 PP |
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 | } | |
272df73e PP |
340 | |
341 | end: | |
342 | return ret; | |
343 | } | |
344 | ||
544d0515 | 345 | int64_t bt_ctf_event_class_get_attribute_count( |
272df73e PP |
346 | struct bt_ctf_event_class *event_class) |
347 | { | |
9ac68eb1 | 348 | int64_t ret; |
272df73e PP |
349 | |
350 | if (!event_class) { | |
f8b979f9 | 351 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9ac68eb1 | 352 | ret = (int64_t) -1; |
272df73e PP |
353 | goto end; |
354 | } | |
355 | ||
356 | ret = bt_ctf_attributes_get_count(event_class->attributes); | |
f8b979f9 | 357 | assert(ret >= 0); |
272df73e PP |
358 | |
359 | end: | |
360 | return ret; | |
361 | } | |
362 | ||
363 | const char * | |
9ac68eb1 PP |
364 | bt_ctf_event_class_get_attribute_name_by_index( |
365 | struct bt_ctf_event_class *event_class, uint64_t index) | |
272df73e PP |
366 | { |
367 | const char *ret; | |
368 | ||
369 | if (!event_class) { | |
f8b979f9 | 370 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
371 | ret = NULL; |
372 | goto end; | |
373 | } | |
374 | ||
375 | ret = bt_ctf_attributes_get_field_name(event_class->attributes, index); | |
96373046 | 376 | if (!ret) { |
f8b979f9 PP |
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 | } | |
272df73e PP |
382 | |
383 | end: | |
384 | return ret; | |
385 | } | |
386 | ||
387 | struct bt_value * | |
9ac68eb1 PP |
388 | bt_ctf_event_class_get_attribute_value_by_index( |
389 | struct bt_ctf_event_class *event_class, uint64_t index) | |
272df73e PP |
390 | { |
391 | struct bt_value *ret; | |
392 | ||
393 | if (!event_class) { | |
f8b979f9 | 394 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
395 | ret = NULL; |
396 | goto end; | |
397 | } | |
398 | ||
399 | ret = bt_ctf_attributes_get_field_value(event_class->attributes, index); | |
96373046 | 400 | if (!ret) { |
f8b979f9 PP |
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 | } | |
272df73e PP |
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) { | |
32e87ceb | 418 | BT_LOGW("Invalid parameter: event class or name is NULL: " |
f8b979f9 PP |
419 | "event-class-addr=%p, name-addr=%p", |
420 | event_class, name); | |
272df73e PP |
421 | ret = NULL; |
422 | goto end; | |
423 | } | |
424 | ||
425 | ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes, | |
426 | name); | |
96373046 | 427 | if (!ret) { |
f8b979f9 PP |
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 | } | |
272df73e PP |
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 | { | |
dc3fffef PP |
443 | return event_class ? |
444 | bt_get(bt_ctf_event_class_borrow_stream_class(event_class)) : | |
445 | NULL; | |
272df73e PP |
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) { | |
f8b979f9 | 454 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
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 | ||
835b2d10 | 469 | if (!event_class) { |
f8b979f9 | 470 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
835b2d10 JG |
471 | ret = -1; |
472 | goto end; | |
473 | } | |
474 | ||
475 | if (payload && bt_ctf_field_type_get_type_id(payload) != | |
1487a16a | 476 | BT_CTF_FIELD_TYPE_ID_STRUCT) { |
f8b979f9 PP |
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))); | |
272df73e PP |
484 | ret = -1; |
485 | goto end; | |
486 | } | |
487 | ||
272df73e | 488 | bt_put(event_class->fields); |
835b2d10 | 489 | event_class->fields = bt_get(payload); |
f8b979f9 PP |
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); | |
272df73e PP |
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 | ||
f8b979f9 PP |
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); | |
272df73e PP |
519 | ret = -1; |
520 | goto end; | |
521 | } | |
522 | ||
f8b979f9 PP |
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)); | |
272df73e PP |
528 | ret = -1; |
529 | goto end; | |
530 | } | |
531 | ||
f8b979f9 PP |
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); | |
272df73e PP |
543 | ret = bt_ctf_field_type_structure_add_field(event_class->fields, |
544 | type, name); | |
f8b979f9 PP |
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); | |
272df73e PP |
550 | end: |
551 | return ret; | |
552 | } | |
553 | ||
9ac68eb1 | 554 | int64_t bt_ctf_event_class_get_payload_type_field_count( |
272df73e PP |
555 | struct bt_ctf_event_class *event_class) |
556 | { | |
544d0515 | 557 | int64_t ret; |
272df73e PP |
558 | |
559 | if (!event_class) { | |
f8b979f9 | 560 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9ac68eb1 | 561 | ret = (int64_t) -1; |
272df73e PP |
562 | goto end; |
563 | } | |
564 | ||
f8b979f9 PP |
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)); | |
9ac68eb1 | 570 | ret = (int64_t) -1; |
272df73e PP |
571 | goto end; |
572 | } | |
573 | ||
f8b979f9 PP |
574 | assert(bt_ctf_field_type_get_type_id(event_class->fields) == |
575 | BT_CTF_FIELD_TYPE_ID_STRUCT); | |
272df73e PP |
576 | ret = bt_ctf_field_type_structure_get_field_count(event_class->fields); |
577 | end: | |
578 | return ret; | |
579 | } | |
580 | ||
9ac68eb1 PP |
581 | int bt_ctf_event_class_get_payload_type_field_by_index( |
582 | struct bt_ctf_event_class *event_class, | |
272df73e | 583 | const char **field_name, struct bt_ctf_field_type **field_type, |
9ac68eb1 | 584 | uint64_t index) |
272df73e PP |
585 | { |
586 | int ret; | |
587 | ||
9ac68eb1 | 588 | if (!event_class) { |
f8b979f9 | 589 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
590 | ret = -1; |
591 | goto end; | |
592 | } | |
593 | ||
f8b979f9 PP |
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); | |
272df73e PP |
599 | ret = -1; |
600 | goto end; | |
601 | } | |
602 | ||
f8b979f9 PP |
603 | assert(bt_ctf_field_type_get_type_id(event_class->fields) == |
604 | BT_CTF_FIELD_TYPE_ID_STRUCT); | |
272df73e PP |
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 | ||
9ac68eb1 PP |
611 | struct bt_ctf_field_type * |
612 | bt_ctf_event_class_get_payload_type_field_type_by_name( | |
272df73e PP |
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) { | |
32e87ceb | 619 | BT_LOGW("Invalid parameter: event class or name is NULL: " |
f8b979f9 PP |
620 | "event-class-addr=%p, name-addr=%p", |
621 | event_class, name); | |
272df73e PP |
622 | goto end; |
623 | } | |
624 | ||
f8b979f9 PP |
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)); | |
272df73e PP |
630 | goto end; |
631 | } | |
632 | ||
f8b979f9 PP |
633 | assert(bt_ctf_field_type_get_type_id(event_class->fields) == |
634 | BT_CTF_FIELD_TYPE_ID_STRUCT); | |
272df73e PP |
635 | name_quark = g_quark_try_string(name); |
636 | if (!name_quark) { | |
f8b979f9 | 637 | BT_LOGE("Cannot get GQuark: string=\"%s\"", name); |
272df73e PP |
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 | ||
f8b979f9 PP |
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)); | |
272df73e PP |
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 | ||
f8b979f9 PP |
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)); | |
272df73e PP |
692 | ret = -1; |
693 | goto end; | |
694 | } | |
695 | ||
835b2d10 | 696 | if (context && bt_ctf_field_type_get_type_id(context) != |
1487a16a | 697 | BT_CTF_FIELD_TYPE_ID_STRUCT) { |
f8b979f9 PP |
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))); | |
272df73e PP |
705 | ret = -1; |
706 | goto end; | |
707 | } | |
708 | ||
272df73e | 709 | bt_put(event_class->context); |
835b2d10 | 710 | event_class->context = bt_get(context); |
f8b979f9 PP |
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); | |
272df73e PP |
716 | end: |
717 | return ret; | |
718 | ||
719 | } | |
720 | ||
f8b979f9 | 721 | /* Pre-2.0 CTF writer backward compatibility */ |
272df73e PP |
722 | void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class) |
723 | { | |
724 | bt_get(event_class); | |
725 | } | |
726 | ||
f8b979f9 | 727 | /* Pre-2.0 CTF writer backward compatibility */ |
272df73e PP |
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, | |
9ac68eb1 | 735 | uint64_t stream_id_param) |
272df73e PP |
736 | { |
737 | int ret = 0; | |
9ac68eb1 PP |
738 | struct bt_value *obj = NULL; |
739 | int64_t stream_id = (int64_t) stream_id_param; | |
740 | ||
741 | assert(event_class); | |
f8b979f9 | 742 | assert(stream_id >= 0); |
272df73e | 743 | obj = bt_value_integer_create_init(stream_id); |
272df73e | 744 | if (!obj) { |
f8b979f9 | 745 | BT_LOGE_STR("Cannot create integer value object."); |
272df73e PP |
746 | ret = -1; |
747 | goto end; | |
748 | } | |
749 | ||
750 | ret = bt_ctf_attributes_set_field_value(event_class->attributes, | |
751 | "stream_id", obj); | |
f8b979f9 PP |
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 | } | |
272df73e PP |
759 | |
760 | if (event_class->frozen) { | |
f8b979f9 | 761 | BT_LOGV_STR("Freezing event class's attributes because event class is frozen."); |
272df73e PP |
762 | bt_ctf_attributes_freeze(event_class->attributes); |
763 | } | |
764 | ||
f8b979f9 PP |
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 | ||
272df73e PP |
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); | |
f8b979f9 PP |
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)); | |
0352f8fa | 785 | BT_LOGD_STR("Destroying event class's attributes."); |
272df73e | 786 | bt_ctf_attributes_destroy(event_class->attributes); |
03409974 | 787 | BT_LOGD_STR("Putting context field type."); |
272df73e | 788 | bt_put(event_class->context); |
03409974 | 789 | BT_LOGD_STR("Putting payload field type."); |
272df73e PP |
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); | |
f8b979f9 PP |
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)); | |
272df73e | 806 | event_class->frozen = 1; |
5990dd44 JG |
807 | event_class->name = bt_ctf_event_class_get_name(event_class); |
808 | event_class->id = bt_ctf_event_class_get_id(event_class); | |
0352f8fa | 809 | BT_LOGD_STR("Freezing event class's context field type."); |
272df73e | 810 | bt_ctf_field_type_freeze(event_class->context); |
0352f8fa | 811 | BT_LOGD_STR("Freezing event class's payload field type."); |
272df73e | 812 | bt_ctf_field_type_freeze(event_class->fields); |
0352f8fa | 813 | BT_LOGD_STR("Freezing event class's attributes."); |
272df73e PP |
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 | { | |
544d0515 PP |
821 | int64_t i; |
822 | int64_t count; | |
272df73e PP |
823 | int ret = 0; |
824 | struct bt_value *attr_value = NULL; | |
825 | ||
826 | assert(event_class); | |
827 | assert(context); | |
f8b979f9 PP |
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); | |
272df73e PP |
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); | |
f8b979f9 | 837 | assert(count >= 0); |
272df73e PP |
838 | |
839 | for (i = 0; i < count; ++i) { | |
840 | const char *attr_name = NULL; | |
841 | ||
9ac68eb1 | 842 | attr_name = bt_ctf_event_class_get_attribute_name_by_index( |
272df73e | 843 | event_class, i); |
f8b979f9 | 844 | assert(attr_name); |
9ac68eb1 | 845 | attr_value = bt_ctf_event_class_get_attribute_value_by_index( |
272df73e | 846 | event_class, i); |
f8b979f9 | 847 | assert(attr_value); |
272df73e PP |
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); | |
f8b979f9 | 855 | assert(ret == 0); |
272df73e PP |
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); | |
f8b979f9 | 866 | assert(ret == 0); |
272df73e PP |
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 */ | |
0fbb9a9f | 874 | abort(); |
272df73e PP |
875 | break; |
876 | } | |
877 | ||
878 | BT_PUT(attr_value); | |
879 | } | |
880 | ||
881 | if (event_class->context) { | |
882 | g_string_append(context->string, "\tcontext := "); | |
0352f8fa | 883 | BT_LOGD_STR("Serializing event class's context field type metadata."); |
272df73e PP |
884 | ret = bt_ctf_field_type_serialize(event_class->context, |
885 | context); | |
886 | if (ret) { | |
66871d36 | 887 | BT_LOGW("Cannot serialize event class's context field type's metadata: " |
f8b979f9 | 888 | "ret=%d", ret); |
272df73e PP |
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 := "); | |
0352f8fa | 896 | BT_LOGD_STR("Serializing event class's payload field type metadata."); |
272df73e PP |
897 | ret = bt_ctf_field_type_serialize(event_class->fields, context); |
898 | if (ret) { | |
66871d36 | 899 | BT_LOGW("Cannot serialize event class's payload field type's metadata: " |
f8b979f9 | 900 | "ret=%d", ret); |
272df73e PP |
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 | } |