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> | |
2a3ced3c | 41 | #include <babeltrace/ctf-ir/utils-internal.h> |
272df73e PP |
42 | #include <babeltrace/ref.h> |
43 | #include <babeltrace/ctf-ir/attributes-internal.h> | |
3d9990ac PP |
44 | #include <babeltrace/compiler-internal.h> |
45 | #include <babeltrace/endian-internal.h> | |
c55a9f58 | 46 | #include <babeltrace/types.h> |
f8b979f9 | 47 | #include <babeltrace/values-internal.h> |
dc3fffef | 48 | #include <inttypes.h> |
0fbb9a9f | 49 | #include <stdlib.h> |
272df73e PP |
50 | |
51 | static | |
50842bdc | 52 | void bt_event_class_destroy(struct bt_object *obj); |
272df73e | 53 | |
50842bdc | 54 | struct bt_event_class *bt_event_class_create(const char *name) |
272df73e | 55 | { |
272df73e | 56 | struct bt_value *obj = NULL; |
50842bdc | 57 | struct bt_event_class *event_class = NULL; |
272df73e | 58 | |
f8b979f9 PP |
59 | BT_LOGD("Creating event class object: name=\"%s\"", |
60 | name); | |
61 | ||
cf76ce92 PP |
62 | if (!name) { |
63 | BT_LOGW_STR("Invalid parameter: name is NULL."); | |
64 | goto error; | |
65 | } | |
66 | ||
50842bdc | 67 | event_class = g_new0(struct bt_event_class, 1); |
272df73e | 68 | if (!event_class) { |
f8b979f9 | 69 | BT_LOGE_STR("Failed to allocate one event class."); |
272df73e PP |
70 | goto error; |
71 | } | |
72 | ||
50842bdc PP |
73 | bt_object_init(event_class, bt_event_class_destroy); |
74 | event_class->fields = bt_field_type_structure_create(); | |
272df73e | 75 | if (!event_class->fields) { |
f8b979f9 | 76 | BT_LOGE_STR("Cannot create event class's initial payload field type object."); |
272df73e PP |
77 | goto error; |
78 | } | |
79 | ||
cf76ce92 PP |
80 | event_class->id = -1; |
81 | event_class->name = g_string_new(name); | |
82 | if (!event_class->name) { | |
83 | BT_LOGE_STR("Failed to allocate a GString."); | |
272df73e PP |
84 | goto error; |
85 | } | |
86 | ||
cf76ce92 PP |
87 | event_class->emf_uri = g_string_new(NULL); |
88 | if (!event_class->emf_uri) { | |
89 | BT_LOGE_STR("Failed to allocate a GString."); | |
272df73e PP |
90 | goto error; |
91 | } | |
92 | ||
50842bdc | 93 | event_class->log_level = BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED; |
272df73e | 94 | BT_PUT(obj); |
f8b979f9 | 95 | BT_LOGD("Created event class object: addr=%p, name=\"%s\"", |
50842bdc | 96 | event_class, bt_event_class_get_name(event_class)); |
272df73e PP |
97 | return event_class; |
98 | ||
99 | error: | |
100 | BT_PUT(event_class); | |
101 | BT_PUT(obj); | |
102 | return event_class; | |
103 | } | |
104 | ||
50842bdc | 105 | const char *bt_event_class_get_name(struct bt_event_class *event_class) |
272df73e | 106 | { |
272df73e PP |
107 | const char *name = NULL; |
108 | ||
109 | if (!event_class) { | |
f8b979f9 | 110 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
111 | goto end; |
112 | } | |
113 | ||
cf76ce92 | 114 | name = event_class->name->str; |
272df73e PP |
115 | |
116 | end: | |
272df73e PP |
117 | return name; |
118 | } | |
119 | ||
50842bdc | 120 | int64_t bt_event_class_get_id(struct bt_event_class *event_class) |
272df73e | 121 | { |
272df73e PP |
122 | int64_t ret = 0; |
123 | ||
124 | if (!event_class) { | |
f8b979f9 | 125 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9ac68eb1 | 126 | ret = (int64_t) -1; |
272df73e PP |
127 | goto end; |
128 | } | |
129 | ||
cf76ce92 | 130 | ret = event_class->id; |
272df73e PP |
131 | |
132 | end: | |
272df73e PP |
133 | return ret; |
134 | } | |
135 | ||
50842bdc | 136 | int bt_event_class_set_id(struct bt_event_class *event_class, |
9ac68eb1 | 137 | uint64_t id_param) |
272df73e PP |
138 | { |
139 | int ret = 0; | |
9ac68eb1 | 140 | int64_t id = (int64_t) id_param; |
272df73e | 141 | |
f8b979f9 PP |
142 | if (!event_class) { |
143 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
272df73e PP |
144 | ret = -1; |
145 | goto end; | |
146 | } | |
147 | ||
f8b979f9 PP |
148 | if (event_class->frozen) { |
149 | BT_LOGW("Invalid parameter: event class is frozen: " | |
150 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
151 | event_class, bt_event_class_get_name(event_class), |
152 | bt_event_class_get_id(event_class)); | |
272df73e PP |
153 | ret = -1; |
154 | goto end; | |
155 | } | |
156 | ||
f8b979f9 PP |
157 | if (id < 0) { |
158 | BT_LOGW("Invalid parameter: invalid event class's ID: " | |
159 | "addr=%p, name=\"%s\", id=%" PRIu64, | |
50842bdc | 160 | event_class, bt_event_class_get_name(event_class), |
f8b979f9 | 161 | id_param); |
272df73e PP |
162 | ret = -1; |
163 | goto end; | |
164 | } | |
165 | ||
cf76ce92 | 166 | event_class->id = id; |
f8b979f9 PP |
167 | BT_LOGV("Set event class's ID: " |
168 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc | 169 | event_class, bt_event_class_get_name(event_class), id); |
f8b979f9 | 170 | |
272df73e | 171 | end: |
272df73e PP |
172 | return ret; |
173 | } | |
174 | ||
50842bdc PP |
175 | enum bt_event_class_log_level bt_event_class_get_log_level( |
176 | struct bt_event_class *event_class) | |
cf76ce92 | 177 | { |
50842bdc | 178 | enum bt_event_class_log_level log_level; |
cf76ce92 PP |
179 | |
180 | if (!event_class) { | |
181 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
50842bdc | 182 | log_level = BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN; |
cf76ce92 PP |
183 | goto end; |
184 | } | |
185 | ||
186 | log_level = event_class->log_level; | |
187 | ||
188 | end: | |
189 | return log_level; | |
190 | } | |
191 | ||
50842bdc PP |
192 | int bt_event_class_set_log_level(struct bt_event_class *event_class, |
193 | enum bt_event_class_log_level log_level) | |
272df73e PP |
194 | { |
195 | int ret = 0; | |
196 | ||
cf76ce92 PP |
197 | if (!event_class) { |
198 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
f8b979f9 PP |
199 | ret = -1; |
200 | goto end; | |
201 | } | |
202 | ||
203 | if (event_class->frozen) { | |
204 | BT_LOGW("Invalid parameter: event class is frozen: " | |
cf76ce92 | 205 | "addr=%p, name=\"%s\", id=%" PRId64, |
50842bdc PP |
206 | event_class, bt_event_class_get_name(event_class), |
207 | bt_event_class_get_id(event_class)); | |
272df73e PP |
208 | ret = -1; |
209 | goto end; | |
210 | } | |
211 | ||
cf76ce92 | 212 | switch (log_level) { |
50842bdc PP |
213 | case BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED: |
214 | case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY: | |
215 | case BT_EVENT_CLASS_LOG_LEVEL_ALERT: | |
216 | case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL: | |
217 | case BT_EVENT_CLASS_LOG_LEVEL_ERROR: | |
218 | case BT_EVENT_CLASS_LOG_LEVEL_WARNING: | |
219 | case BT_EVENT_CLASS_LOG_LEVEL_NOTICE: | |
220 | case BT_EVENT_CLASS_LOG_LEVEL_INFO: | |
221 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM: | |
222 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM: | |
223 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS: | |
224 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE: | |
225 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT: | |
226 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION: | |
227 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE: | |
228 | case BT_EVENT_CLASS_LOG_LEVEL_DEBUG: | |
cf76ce92 PP |
229 | break; |
230 | default: | |
231 | BT_LOGW("Invalid parameter: unknown event class log level: " | |
232 | "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%d", | |
50842bdc PP |
233 | event_class, bt_event_class_get_name(event_class), |
234 | bt_event_class_get_id(event_class), log_level); | |
272df73e PP |
235 | ret = -1; |
236 | goto end; | |
237 | } | |
238 | ||
cf76ce92 PP |
239 | event_class->log_level = log_level; |
240 | BT_LOGV("Set event class's log level: " | |
241 | "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%s", | |
50842bdc PP |
242 | event_class, bt_event_class_get_name(event_class), |
243 | bt_event_class_get_id(event_class), | |
244 | bt_event_class_log_level_string(log_level)); | |
272df73e PP |
245 | |
246 | end: | |
247 | return ret; | |
248 | } | |
249 | ||
50842bdc PP |
250 | const char *bt_event_class_get_emf_uri( |
251 | struct bt_event_class *event_class) | |
272df73e | 252 | { |
cf76ce92 | 253 | const char *emf_uri = NULL; |
272df73e PP |
254 | |
255 | if (!event_class) { | |
f8b979f9 | 256 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
257 | goto end; |
258 | } | |
259 | ||
cf76ce92 PP |
260 | if (event_class->emf_uri->len > 0) { |
261 | emf_uri = event_class->emf_uri->str; | |
262 | } | |
272df73e PP |
263 | |
264 | end: | |
cf76ce92 | 265 | return emf_uri; |
272df73e PP |
266 | } |
267 | ||
50842bdc | 268 | int bt_event_class_set_emf_uri(struct bt_event_class *event_class, |
cf76ce92 | 269 | const char *emf_uri) |
272df73e | 270 | { |
cf76ce92 | 271 | int ret = 0; |
272df73e PP |
272 | |
273 | if (!event_class) { | |
f8b979f9 | 274 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
cf76ce92 | 275 | ret = -1; |
272df73e PP |
276 | goto end; |
277 | } | |
278 | ||
cf76ce92 PP |
279 | if (emf_uri && strlen(emf_uri) == 0) { |
280 | BT_LOGW_STR("Invalid parameter: EMF URI is empty."); | |
281 | ret = -1; | |
272df73e PP |
282 | goto end; |
283 | } | |
284 | ||
cf76ce92 PP |
285 | if (event_class->frozen) { |
286 | BT_LOGW("Invalid parameter: event class is frozen: " | |
287 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
288 | event_class, bt_event_class_get_name(event_class), |
289 | bt_event_class_get_id(event_class)); | |
cf76ce92 | 290 | ret = -1; |
272df73e PP |
291 | goto end; |
292 | } | |
293 | ||
cf76ce92 PP |
294 | if (emf_uri) { |
295 | g_string_assign(event_class->emf_uri, emf_uri); | |
296 | BT_LOGV("Set event class's EMF URI: " | |
297 | "addr=%p, name=\"%s\", id=%" PRId64 ", emf-uri=\"%s\"", | |
50842bdc PP |
298 | event_class, bt_event_class_get_name(event_class), |
299 | bt_event_class_get_id(event_class), emf_uri); | |
cf76ce92 PP |
300 | } else { |
301 | g_string_assign(event_class->emf_uri, ""); | |
302 | BT_LOGV("Reset event class's EMF URI: " | |
303 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
304 | event_class, bt_event_class_get_name(event_class), |
305 | bt_event_class_get_id(event_class)); | |
f8b979f9 | 306 | } |
272df73e PP |
307 | |
308 | end: | |
309 | return ret; | |
272df73e PP |
310 | } |
311 | ||
50842bdc PP |
312 | struct bt_stream_class *bt_event_class_get_stream_class( |
313 | struct bt_event_class *event_class) | |
272df73e | 314 | { |
dc3fffef | 315 | return event_class ? |
50842bdc | 316 | bt_get(bt_event_class_borrow_stream_class(event_class)) : |
dc3fffef | 317 | NULL; |
272df73e PP |
318 | } |
319 | ||
50842bdc PP |
320 | struct bt_field_type *bt_event_class_get_payload_type( |
321 | struct bt_event_class *event_class) | |
272df73e | 322 | { |
50842bdc | 323 | struct bt_field_type *payload = NULL; |
272df73e PP |
324 | |
325 | if (!event_class) { | |
f8b979f9 | 326 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
327 | goto end; |
328 | } | |
329 | ||
330 | bt_get(event_class->fields); | |
331 | payload = event_class->fields; | |
332 | end: | |
333 | return payload; | |
334 | } | |
335 | ||
50842bdc PP |
336 | int bt_event_class_set_payload_type(struct bt_event_class *event_class, |
337 | struct bt_field_type *payload) | |
272df73e PP |
338 | { |
339 | int ret = 0; | |
340 | ||
835b2d10 | 341 | if (!event_class) { |
f8b979f9 | 342 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
835b2d10 JG |
343 | ret = -1; |
344 | goto end; | |
345 | } | |
346 | ||
50842bdc PP |
347 | if (payload && bt_field_type_get_type_id(payload) != |
348 | BT_FIELD_TYPE_ID_STRUCT) { | |
f8b979f9 PP |
349 | BT_LOGW("Invalid parameter: event class's payload field type must be a structure: " |
350 | "addr=%p, name=\"%s\", id=%" PRId64 ", " | |
351 | "payload-ft-addr=%p, payload-ft-id=%s", | |
50842bdc PP |
352 | event_class, bt_event_class_get_name(event_class), |
353 | bt_event_class_get_id(event_class), payload, | |
354 | bt_field_type_id_string( | |
355 | bt_field_type_get_type_id(payload))); | |
272df73e PP |
356 | ret = -1; |
357 | goto end; | |
358 | } | |
359 | ||
272df73e | 360 | bt_put(event_class->fields); |
835b2d10 | 361 | event_class->fields = bt_get(payload); |
f8b979f9 PP |
362 | BT_LOGV("Set event class's payload field type: " |
363 | "event-class-addr=%p, event-class-name=\"%s\", " | |
364 | "event-class-id=%" PRId64 ", payload-ft-addr=%p", | |
50842bdc PP |
365 | event_class, bt_event_class_get_name(event_class), |
366 | bt_event_class_get_id(event_class), payload); | |
272df73e PP |
367 | end: |
368 | return ret; | |
369 | } | |
370 | ||
50842bdc PP |
371 | int bt_event_class_add_field(struct bt_event_class *event_class, |
372 | struct bt_field_type *type, | |
272df73e PP |
373 | const char *name) |
374 | { | |
375 | int ret = 0; | |
376 | ||
f8b979f9 PP |
377 | if (!event_class || !type) { |
378 | BT_LOGW("Invalid parameter: event class or field type is NULL: " | |
379 | "event-class-addr=%p, field-type-addr=%p", | |
380 | event_class, type); | |
381 | ret = -1; | |
382 | goto end; | |
383 | } | |
384 | ||
f4cc9a21 | 385 | if (!bt_identifier_is_valid(name)) { |
f8b979f9 PP |
386 | BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: " |
387 | "addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"", | |
50842bdc PP |
388 | event_class, bt_event_class_get_name(event_class), |
389 | bt_event_class_get_id(event_class), | |
f8b979f9 | 390 | name); |
272df73e PP |
391 | ret = -1; |
392 | goto end; | |
393 | } | |
394 | ||
f8b979f9 PP |
395 | if (event_class->frozen) { |
396 | BT_LOGW("Invalid parameter: event class is frozen: " | |
397 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
398 | event_class, bt_event_class_get_name(event_class), |
399 | bt_event_class_get_id(event_class)); | |
272df73e PP |
400 | ret = -1; |
401 | goto end; | |
402 | } | |
403 | ||
f8b979f9 PP |
404 | if (!event_class->fields) { |
405 | BT_LOGW("Event class has no payload field type: " | |
406 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
407 | event_class, bt_event_class_get_name(event_class), |
408 | bt_event_class_get_id(event_class)); | |
f8b979f9 PP |
409 | ret = -1; |
410 | goto end; | |
411 | } | |
412 | ||
50842bdc PP |
413 | assert(bt_field_type_get_type_id(event_class->fields) == |
414 | BT_FIELD_TYPE_ID_STRUCT); | |
415 | ret = bt_field_type_structure_add_field(event_class->fields, | |
272df73e | 416 | type, name); |
f8b979f9 PP |
417 | BT_LOGV("Added field to event class's payload field type: " |
418 | "event-class-addr=%p, event-class-name=\"%s\", " | |
419 | "event-class-id=%" PRId64 ", field-name=\"%s\", ft-addr=%p", | |
50842bdc PP |
420 | event_class, bt_event_class_get_name(event_class), |
421 | bt_event_class_get_id(event_class), name, type); | |
272df73e PP |
422 | end: |
423 | return ret; | |
424 | } | |
425 | ||
50842bdc PP |
426 | int64_t bt_event_class_get_payload_type_field_count( |
427 | struct bt_event_class *event_class) | |
272df73e | 428 | { |
544d0515 | 429 | int64_t ret; |
272df73e PP |
430 | |
431 | if (!event_class) { | |
f8b979f9 | 432 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
9ac68eb1 | 433 | ret = (int64_t) -1; |
272df73e PP |
434 | goto end; |
435 | } | |
436 | ||
f8b979f9 PP |
437 | if (!event_class->fields) { |
438 | BT_LOGV("Event class has no payload field type: " | |
439 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
440 | event_class, bt_event_class_get_name(event_class), |
441 | bt_event_class_get_id(event_class)); | |
9ac68eb1 | 442 | ret = (int64_t) -1; |
272df73e PP |
443 | goto end; |
444 | } | |
445 | ||
50842bdc PP |
446 | assert(bt_field_type_get_type_id(event_class->fields) == |
447 | BT_FIELD_TYPE_ID_STRUCT); | |
448 | ret = bt_field_type_structure_get_field_count(event_class->fields); | |
272df73e PP |
449 | end: |
450 | return ret; | |
451 | } | |
452 | ||
50842bdc PP |
453 | int bt_event_class_get_payload_type_field_by_index( |
454 | struct bt_event_class *event_class, | |
455 | const char **field_name, struct bt_field_type **field_type, | |
9ac68eb1 | 456 | uint64_t index) |
272df73e PP |
457 | { |
458 | int ret; | |
459 | ||
9ac68eb1 | 460 | if (!event_class) { |
f8b979f9 | 461 | BT_LOGW_STR("Invalid parameter: event class is NULL."); |
272df73e PP |
462 | ret = -1; |
463 | goto end; | |
464 | } | |
465 | ||
f8b979f9 PP |
466 | if (!event_class->fields) { |
467 | BT_LOGV("Event class has no payload field type: " | |
468 | "addr=%p, name=\"%s\", id=%" PRId64 ", index=%" PRIu64, | |
50842bdc PP |
469 | event_class, bt_event_class_get_name(event_class), |
470 | bt_event_class_get_id(event_class), index); | |
272df73e PP |
471 | ret = -1; |
472 | goto end; | |
473 | } | |
474 | ||
50842bdc PP |
475 | assert(bt_field_type_get_type_id(event_class->fields) == |
476 | BT_FIELD_TYPE_ID_STRUCT); | |
477 | ret = bt_field_type_structure_get_field_by_index(event_class->fields, | |
272df73e PP |
478 | field_name, field_type, index); |
479 | end: | |
480 | return ret; | |
481 | } | |
482 | ||
50842bdc PP |
483 | struct bt_field_type * |
484 | bt_event_class_get_payload_type_field_type_by_name( | |
485 | struct bt_event_class *event_class, const char *name) | |
272df73e PP |
486 | { |
487 | GQuark name_quark; | |
50842bdc | 488 | struct bt_field_type *field_type = NULL; |
272df73e PP |
489 | |
490 | if (!event_class || !name) { | |
32e87ceb | 491 | BT_LOGW("Invalid parameter: event class or name is NULL: " |
f8b979f9 PP |
492 | "event-class-addr=%p, name-addr=%p", |
493 | event_class, name); | |
272df73e PP |
494 | goto end; |
495 | } | |
496 | ||
f8b979f9 PP |
497 | if (!event_class->fields) { |
498 | BT_LOGV("Event class has no payload field type: " | |
499 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
500 | event_class, bt_event_class_get_name(event_class), |
501 | bt_event_class_get_id(event_class)); | |
272df73e PP |
502 | goto end; |
503 | } | |
504 | ||
50842bdc PP |
505 | assert(bt_field_type_get_type_id(event_class->fields) == |
506 | BT_FIELD_TYPE_ID_STRUCT); | |
272df73e PP |
507 | name_quark = g_quark_try_string(name); |
508 | if (!name_quark) { | |
f8b979f9 | 509 | BT_LOGE("Cannot get GQuark: string=\"%s\"", name); |
272df73e PP |
510 | goto end; |
511 | } | |
512 | ||
513 | /* | |
514 | * No need to increment field_type's reference count since getting it | |
515 | * from the structure already does. | |
516 | */ | |
50842bdc | 517 | field_type = bt_field_type_structure_get_field_type_by_name( |
272df73e PP |
518 | event_class->fields, name); |
519 | end: | |
520 | return field_type; | |
521 | } | |
522 | ||
50842bdc PP |
523 | struct bt_field_type *bt_event_class_get_context_type( |
524 | struct bt_event_class *event_class) | |
272df73e | 525 | { |
50842bdc | 526 | struct bt_field_type *context_type = NULL; |
272df73e | 527 | |
f8b979f9 PP |
528 | if (!event_class) { |
529 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
530 | goto end; | |
531 | } | |
532 | ||
533 | if (!event_class->context) { | |
534 | BT_LOGV("Event class has no context field type: " | |
535 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
536 | event_class, bt_event_class_get_name(event_class), |
537 | bt_event_class_get_id(event_class)); | |
272df73e PP |
538 | goto end; |
539 | } | |
540 | ||
541 | bt_get(event_class->context); | |
542 | context_type = event_class->context; | |
543 | end: | |
544 | return context_type; | |
545 | } | |
546 | ||
50842bdc PP |
547 | int bt_event_class_set_context_type( |
548 | struct bt_event_class *event_class, | |
549 | struct bt_field_type *context) | |
272df73e PP |
550 | { |
551 | int ret = 0; | |
552 | ||
f8b979f9 PP |
553 | if (!event_class) { |
554 | BT_LOGW_STR("Invalid parameter: event class is NULL."); | |
555 | ret = -1; | |
556 | goto end; | |
557 | } | |
558 | ||
559 | if (event_class->frozen) { | |
560 | BT_LOGW("Invalid parameter: event class is frozen: " | |
561 | "addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
562 | event_class, bt_event_class_get_name(event_class), |
563 | bt_event_class_get_id(event_class)); | |
272df73e PP |
564 | ret = -1; |
565 | goto end; | |
566 | } | |
567 | ||
50842bdc PP |
568 | if (context && bt_field_type_get_type_id(context) != |
569 | BT_FIELD_TYPE_ID_STRUCT) { | |
f8b979f9 PP |
570 | BT_LOGW("Invalid parameter: event class's context field type must be a structure: " |
571 | "addr=%p, name=\"%s\", id=%" PRId64 ", " | |
572 | "context-ft-id=%s", | |
50842bdc PP |
573 | event_class, bt_event_class_get_name(event_class), |
574 | bt_event_class_get_id(event_class), | |
575 | bt_field_type_id_string( | |
576 | bt_field_type_get_type_id(context))); | |
272df73e PP |
577 | ret = -1; |
578 | goto end; | |
579 | } | |
580 | ||
272df73e | 581 | bt_put(event_class->context); |
835b2d10 | 582 | event_class->context = bt_get(context); |
f8b979f9 PP |
583 | BT_LOGV("Set event class's context field type: " |
584 | "event-class-addr=%p, event-class-name=\"%s\", " | |
585 | "event-class-id=%" PRId64 ", context-ft-addr=%p", | |
50842bdc PP |
586 | event_class, bt_event_class_get_name(event_class), |
587 | bt_event_class_get_id(event_class), context); | |
272df73e PP |
588 | end: |
589 | return ret; | |
590 | ||
591 | } | |
592 | ||
f8b979f9 | 593 | /* Pre-2.0 CTF writer backward compatibility */ |
50842bdc | 594 | void bt_ctf_event_class_get(struct bt_event_class *event_class) |
272df73e PP |
595 | { |
596 | bt_get(event_class); | |
597 | } | |
598 | ||
f8b979f9 | 599 | /* Pre-2.0 CTF writer backward compatibility */ |
50842bdc | 600 | void bt_ctf_event_class_put(struct bt_event_class *event_class) |
272df73e PP |
601 | { |
602 | bt_put(event_class); | |
603 | } | |
604 | ||
272df73e | 605 | static |
50842bdc | 606 | void bt_event_class_destroy(struct bt_object *obj) |
272df73e | 607 | { |
50842bdc | 608 | struct bt_event_class *event_class; |
272df73e | 609 | |
50842bdc | 610 | event_class = container_of(obj, struct bt_event_class, base); |
f8b979f9 | 611 | BT_LOGD("Destroying event class: addr=%p, name=\"%s\", id=%" PRId64, |
50842bdc PP |
612 | event_class, bt_event_class_get_name(event_class), |
613 | bt_event_class_get_id(event_class)); | |
cf76ce92 PP |
614 | g_string_free(event_class->name, TRUE); |
615 | g_string_free(event_class->emf_uri, TRUE); | |
03409974 | 616 | BT_LOGD_STR("Putting context field type."); |
272df73e | 617 | bt_put(event_class->context); |
03409974 | 618 | BT_LOGD_STR("Putting payload field type."); |
272df73e PP |
619 | bt_put(event_class->fields); |
620 | g_free(event_class); | |
621 | } | |
622 | ||
623 | BT_HIDDEN | |
50842bdc | 624 | void bt_event_class_freeze(struct bt_event_class *event_class) |
272df73e PP |
625 | { |
626 | assert(event_class); | |
f8b979f9 PP |
627 | |
628 | if (event_class->frozen) { | |
629 | return; | |
630 | } | |
631 | ||
632 | BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64, | |
50842bdc PP |
633 | event_class, bt_event_class_get_name(event_class), |
634 | bt_event_class_get_id(event_class)); | |
272df73e | 635 | event_class->frozen = 1; |
0352f8fa | 636 | BT_LOGD_STR("Freezing event class's context field type."); |
50842bdc | 637 | bt_field_type_freeze(event_class->context); |
0352f8fa | 638 | BT_LOGD_STR("Freezing event class's payload field type."); |
50842bdc | 639 | bt_field_type_freeze(event_class->fields); |
272df73e PP |
640 | } |
641 | ||
642 | BT_HIDDEN | |
50842bdc | 643 | int bt_event_class_serialize(struct bt_event_class *event_class, |
272df73e PP |
644 | struct metadata_context *context) |
645 | { | |
272df73e PP |
646 | int ret = 0; |
647 | struct bt_value *attr_value = NULL; | |
648 | ||
649 | assert(event_class); | |
650 | assert(context); | |
f8b979f9 PP |
651 | BT_LOGD("Serializing event class's metadata: " |
652 | "event-class-addr=%p, event-class-name=\"%s\", " | |
653 | "event-class-id=%" PRId64 ", metadata-context-addr=%p", | |
50842bdc PP |
654 | event_class, bt_event_class_get_name(event_class), |
655 | bt_event_class_get_id(event_class), context); | |
272df73e PP |
656 | context->current_indentation_level = 1; |
657 | g_string_assign(context->field_name, ""); | |
658 | g_string_append(context->string, "event {\n"); | |
272df73e | 659 | |
cf76ce92 PP |
660 | /* Serialize attributes */ |
661 | g_string_append_printf(context->string, "\tname = \"%s\";\n", | |
662 | event_class->name->str); | |
663 | assert(event_class->id >= 0); | |
664 | g_string_append_printf(context->string, "\tid = %" PRId64 ";\n", | |
665 | event_class->id); | |
666 | g_string_append_printf(context->string, "\tstream_id = %" PRId64 ";\n", | |
50842bdc PP |
667 | bt_stream_class_get_id( |
668 | bt_event_class_borrow_stream_class(event_class))); | |
272df73e | 669 | |
50842bdc | 670 | if (event_class->log_level != BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) { |
cf76ce92 PP |
671 | g_string_append_printf(context->string, "\tloglevel = %d;\n", |
672 | (int) event_class->log_level); | |
673 | } | |
272df73e | 674 | |
cf76ce92 PP |
675 | if (event_class->emf_uri->len > 0) { |
676 | g_string_append_printf(context->string, "\tmodel.emf.uri = \"%s\";\n", | |
677 | event_class->emf_uri->str); | |
272df73e PP |
678 | } |
679 | ||
cf76ce92 | 680 | /* Serialize context field type */ |
272df73e PP |
681 | if (event_class->context) { |
682 | g_string_append(context->string, "\tcontext := "); | |
0352f8fa | 683 | BT_LOGD_STR("Serializing event class's context field type metadata."); |
50842bdc | 684 | ret = bt_field_type_serialize(event_class->context, |
272df73e PP |
685 | context); |
686 | if (ret) { | |
66871d36 | 687 | BT_LOGW("Cannot serialize event class's context field type's metadata: " |
f8b979f9 | 688 | "ret=%d", ret); |
272df73e PP |
689 | goto end; |
690 | } | |
691 | g_string_append(context->string, ";\n"); | |
692 | } | |
693 | ||
cf76ce92 | 694 | /* Serialize payload field type */ |
272df73e PP |
695 | if (event_class->fields) { |
696 | g_string_append(context->string, "\tfields := "); | |
0352f8fa | 697 | BT_LOGD_STR("Serializing event class's payload field type metadata."); |
50842bdc | 698 | ret = bt_field_type_serialize(event_class->fields, context); |
272df73e | 699 | if (ret) { |
66871d36 | 700 | BT_LOGW("Cannot serialize event class's payload field type's metadata: " |
f8b979f9 | 701 | "ret=%d", ret); |
272df73e PP |
702 | goto end; |
703 | } | |
704 | g_string_append(context->string, ";\n"); | |
705 | } | |
706 | ||
707 | g_string_append(context->string, "};\n\n"); | |
708 | end: | |
709 | context->current_indentation_level = 0; | |
710 | BT_PUT(attr_value); | |
711 | return ret; | |
712 | } | |
2a3ced3c PP |
713 | |
714 | BT_HIDDEN | |
715 | int bt_event_class_validate_single_clock_class( | |
716 | struct bt_event_class *event_class, | |
717 | struct bt_clock_class **expected_clock_class) | |
718 | { | |
719 | int ret = 0; | |
720 | ||
721 | assert(event_class); | |
722 | assert(expected_clock_class); | |
723 | ret = bt_validate_single_clock_class(event_class->context, | |
724 | expected_clock_class); | |
725 | if (ret) { | |
726 | BT_LOGW("Event class's context field type " | |
727 | "is not recursively mapped to the " | |
728 | "expected clock class: " | |
729 | "event-class-addr=%p, " | |
730 | "event-class-name=\"%s\", " | |
731 | "event-class-id=%" PRId64 ", " | |
732 | "ft-addr=%p", | |
733 | event_class, | |
734 | bt_event_class_get_name(event_class), | |
735 | event_class->id, | |
736 | event_class->context); | |
737 | goto end; | |
738 | } | |
739 | ||
740 | ret = bt_validate_single_clock_class(event_class->fields, | |
741 | expected_clock_class); | |
742 | if (ret) { | |
743 | BT_LOGW("Event class's payload field type " | |
744 | "is not recursively mapped to the " | |
745 | "expected clock class: " | |
746 | "event-class-addr=%p, " | |
747 | "event-class-name=\"%s\", " | |
748 | "event-class-id=%" PRId64 ", " | |
749 | "ft-addr=%p", | |
750 | event_class, | |
751 | bt_event_class_get_name(event_class), | |
752 | event_class->id, | |
753 | event_class->fields); | |
754 | goto end; | |
755 | } | |
756 | ||
757 | end: | |
758 | return ret; | |
759 | } |