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