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