Commit | Line | Data |
---|---|---|
9843982d | 1 | /* |
5c5facc7 | 2 | * ctf/events.c |
9843982d JD |
3 | * |
4 | * Babeltrace Library | |
5 | * | |
6 | * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation | |
7 | * | |
8 | * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
9 | * Julien Desfossez <julien.desfossez@efficios.com> | |
10 | * | |
11 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
12 | * of this software and associated documentation files (the "Software"), to deal | |
13 | * in the Software without restriction, including without limitation the rights | |
14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
15 | * copies of the Software, and to permit persons to whom the Software is | |
16 | * furnished to do so, subject to the following conditions: | |
17 | * | |
18 | * The above copyright notice and this permission notice shall be included in | |
19 | * all copies or substantial portions of the Software. | |
c462e188 MD |
20 | * |
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
27 | * SOFTWARE. | |
9843982d JD |
28 | */ |
29 | ||
30 | #include <babeltrace/babeltrace.h> | |
31 | #include <babeltrace/format.h> | |
32 | #include <babeltrace/ctf/events.h> | |
33 | #include <babeltrace/ctf-ir/metadata.h> | |
e4195791 MD |
34 | #include <babeltrace/prio_heap.h> |
35 | #include <babeltrace/iterator-internal.h> | |
36 | #include <babeltrace/ctf/events-internal.h> | |
37 | #include <babeltrace/ctf/metadata.h> | |
9843982d JD |
38 | #include <glib.h> |
39 | ||
c34ea0fa MD |
40 | #include "events-private.h" |
41 | ||
9843982d JD |
42 | /* |
43 | * thread local storage to store the last error that occured | |
44 | * while reading a field, this variable must be accessed by | |
b330165c | 45 | * bt_ctf_field_get_error only |
9843982d JD |
46 | */ |
47 | __thread int bt_ctf_last_field_error = 0; | |
48 | ||
0d69b916 | 49 | const struct bt_definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event, |
46df6b28 | 50 | enum ctf_scope scope) |
9843982d | 51 | { |
0d69b916 | 52 | const struct bt_definition *tmp = NULL; |
554cf424 | 53 | const struct ctf_event_definition *event; |
9843982d | 54 | |
7f89ddce MD |
55 | if (!ctf_event) |
56 | return NULL; | |
57 | ||
58 | event = ctf_event->parent; | |
9843982d JD |
59 | switch (scope) { |
60 | case BT_TRACE_PACKET_HEADER: | |
61 | if (!event->stream) | |
62 | goto error; | |
63 | if (event->stream->trace_packet_header) | |
64 | tmp = &event->stream->trace_packet_header->p; | |
65 | break; | |
66 | case BT_STREAM_PACKET_CONTEXT: | |
67 | if (!event->stream) | |
68 | goto error; | |
69 | if (event->stream->stream_packet_context) | |
70 | tmp = &event->stream->stream_packet_context->p; | |
71 | break; | |
72 | case BT_STREAM_EVENT_HEADER: | |
73 | if (!event->stream) | |
74 | goto error; | |
75 | if (event->stream->stream_event_header) | |
76 | tmp = &event->stream->stream_event_header->p; | |
77 | break; | |
78 | case BT_STREAM_EVENT_CONTEXT: | |
79 | if (!event->stream) | |
80 | goto error; | |
81 | if (event->stream->stream_event_context) | |
82 | tmp = &event->stream->stream_event_context->p; | |
83 | break; | |
84 | case BT_EVENT_CONTEXT: | |
8a4722b0 JD |
85 | if (event->event_context) |
86 | tmp = &event->event_context->p; | |
9843982d JD |
87 | break; |
88 | case BT_EVENT_FIELDS: | |
8a4722b0 JD |
89 | if (event->event_fields) |
90 | tmp = &event->event_fields->p; | |
9843982d JD |
91 | break; |
92 | } | |
93 | return tmp; | |
94 | ||
95 | error: | |
96 | return NULL; | |
97 | } | |
98 | ||
0d69b916 JD |
99 | const struct bt_definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, |
100 | const struct bt_definition *scope, | |
9843982d JD |
101 | const char *field) |
102 | { | |
0d69b916 | 103 | const struct bt_definition *def; |
300d317a | 104 | char *field_underscore; |
9843982d | 105 | |
7f89ddce MD |
106 | if (!ctf_event || !scope || !field) |
107 | return NULL; | |
108 | ||
2b77e6a6 | 109 | def = bt_lookup_definition(scope, field); |
7f89ddce MD |
110 | /* |
111 | * optionally a field can have an underscore prefix, try | |
112 | * to lookup the field with this prefix if it failed | |
113 | */ | |
114 | if (!def) { | |
115 | field_underscore = g_new(char, strlen(field) + 2); | |
116 | field_underscore[0] = '_'; | |
117 | strcpy(&field_underscore[1], field); | |
2b77e6a6 | 118 | def = bt_lookup_definition(scope, field_underscore); |
7f89ddce | 119 | g_free(field_underscore); |
9843982d | 120 | } |
b14d90be | 121 | if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def)) == CTF_TYPE_VARIANT) { |
554cf424 | 122 | const struct definition_variant *variant_definition; |
7f89ddce | 123 | variant_definition = container_of(def, |
554cf424 | 124 | const struct definition_variant, p); |
7f89ddce MD |
125 | return variant_definition->current_field; |
126 | } | |
127 | return def; | |
9843982d JD |
128 | } |
129 | ||
0d69b916 JD |
130 | const struct bt_definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, |
131 | const struct bt_definition *field, | |
9843982d JD |
132 | unsigned int index) |
133 | { | |
0d69b916 | 134 | struct bt_definition *ret = NULL; |
9843982d | 135 | |
7f89ddce MD |
136 | if (!ctf_event || !field) |
137 | return NULL; | |
138 | ||
b14d90be | 139 | if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) { |
9843982d JD |
140 | struct definition_array *array_definition; |
141 | array_definition = container_of(field, | |
142 | struct definition_array, p); | |
dcaa2e7d | 143 | ret = bt_array_index(array_definition, index); |
b14d90be | 144 | } else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_SEQUENCE) { |
9843982d JD |
145 | struct definition_sequence *sequence_definition; |
146 | sequence_definition = container_of(field, | |
147 | struct definition_sequence, p); | |
9ffd39fc | 148 | ret = bt_sequence_index(sequence_definition, index); |
9843982d JD |
149 | } |
150 | return ret; | |
151 | } | |
152 | ||
c50d2a7a | 153 | const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event) |
9843982d | 154 | { |
554cf424 MD |
155 | const struct ctf_event_declaration *event_class; |
156 | const struct ctf_stream_declaration *stream_class; | |
157 | const struct ctf_event_definition *event; | |
9843982d | 158 | |
7f89ddce | 159 | if (!ctf_event) |
9843982d | 160 | return NULL; |
7f89ddce MD |
161 | |
162 | event = ctf_event->parent; | |
9843982d JD |
163 | stream_class = event->stream->stream_class; |
164 | event_class = g_ptr_array_index(stream_class->events_by_id, | |
165 | event->stream->event_id); | |
166 | return g_quark_to_string(event_class->name); | |
167 | } | |
168 | ||
0d69b916 | 169 | const char *bt_ctf_field_name(const struct bt_definition *def) |
9843982d | 170 | { |
217b52c5 | 171 | if (!def || !def->name) |
7f89ddce MD |
172 | return NULL; |
173 | ||
174 | return rem_(g_quark_to_string(def->name)); | |
9843982d JD |
175 | } |
176 | ||
ecc54f11 | 177 | enum ctf_type_id bt_ctf_field_type(const struct bt_declaration *decl) |
9843982d | 178 | { |
2bdfa4cf | 179 | if (!decl) |
7f89ddce MD |
180 | return CTF_TYPE_UNKNOWN; |
181 | ||
2bdfa4cf | 182 | return decl->id; |
9843982d JD |
183 | } |
184 | ||
c50d2a7a | 185 | int bt_ctf_get_field_list(const struct bt_ctf_event *ctf_event, |
0d69b916 JD |
186 | const struct bt_definition *scope, |
187 | struct bt_definition const * const **list, | |
9843982d JD |
188 | unsigned int *count) |
189 | { | |
7f89ddce MD |
190 | if (!ctf_event || !scope || !list || !count) |
191 | return -EINVAL; | |
192 | ||
b14d90be | 193 | switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope))) { |
9843982d JD |
194 | case CTF_TYPE_INTEGER: |
195 | case CTF_TYPE_FLOAT: | |
196 | case CTF_TYPE_STRING: | |
197 | case CTF_TYPE_ENUM: | |
198 | goto error; | |
199 | case CTF_TYPE_STRUCT: | |
200 | { | |
04ae3991 | 201 | const struct definition_struct *def_struct; |
9843982d | 202 | |
04ae3991 | 203 | def_struct = container_of(scope, const struct definition_struct, p); |
9843982d JD |
204 | if (!def_struct) |
205 | goto error; | |
206 | if (def_struct->fields->pdata) { | |
0d69b916 | 207 | *list = (struct bt_definition const* const*) def_struct->fields->pdata; |
9843982d JD |
208 | *count = def_struct->fields->len; |
209 | goto end; | |
210 | } else { | |
211 | goto error; | |
212 | } | |
7f89ddce | 213 | break; |
9843982d JD |
214 | } |
215 | case CTF_TYPE_UNTAGGED_VARIANT: | |
216 | goto error; | |
217 | case CTF_TYPE_VARIANT: | |
218 | { | |
04ae3991 | 219 | const struct definition_variant *def_variant; |
9843982d | 220 | |
04ae3991 | 221 | def_variant = container_of(scope, const struct definition_variant, p); |
9843982d JD |
222 | if (!def_variant) |
223 | goto error; | |
224 | if (def_variant->fields->pdata) { | |
0d69b916 | 225 | *list = (struct bt_definition const* const*) def_variant->fields->pdata; |
9843982d JD |
226 | *count = def_variant->fields->len; |
227 | goto end; | |
228 | } else { | |
229 | goto error; | |
230 | } | |
7f89ddce | 231 | break; |
9843982d JD |
232 | } |
233 | case CTF_TYPE_ARRAY: | |
234 | { | |
04ae3991 | 235 | const struct definition_array *def_array; |
9843982d | 236 | |
04ae3991 | 237 | def_array = container_of(scope, const struct definition_array, p); |
9843982d JD |
238 | if (!def_array) |
239 | goto error; | |
240 | if (def_array->elems->pdata) { | |
0d69b916 | 241 | *list = (struct bt_definition const* const*) def_array->elems->pdata; |
9843982d JD |
242 | *count = def_array->elems->len; |
243 | goto end; | |
244 | } else { | |
245 | goto error; | |
246 | } | |
7f89ddce | 247 | break; |
9843982d JD |
248 | } |
249 | case CTF_TYPE_SEQUENCE: | |
250 | { | |
04ae3991 | 251 | const struct definition_sequence *def_sequence; |
9843982d | 252 | |
04ae3991 | 253 | def_sequence = container_of(scope, const struct definition_sequence, p); |
9843982d JD |
254 | if (!def_sequence) |
255 | goto error; | |
256 | if (def_sequence->elems->pdata) { | |
0d69b916 | 257 | *list = (struct bt_definition const* const*) def_sequence->elems->pdata; |
61bb7909 | 258 | *count = (unsigned int) def_sequence->length->value._unsigned; |
9843982d JD |
259 | goto end; |
260 | } else { | |
261 | goto error; | |
262 | } | |
7f89ddce | 263 | break; |
9843982d JD |
264 | } |
265 | default: | |
266 | break; | |
267 | } | |
268 | ||
269 | end: | |
270 | return 0; | |
271 | ||
272 | error: | |
273 | *list = NULL; | |
274 | *count = 0; | |
275 | return -1; | |
276 | } | |
277 | ||
c50d2a7a | 278 | struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event) |
98a04903 JD |
279 | { |
280 | struct bt_context *ret = NULL; | |
554cf424 MD |
281 | const struct ctf_file_stream *cfs; |
282 | const struct ctf_trace *trace; | |
283 | const struct ctf_event_definition *event; | |
98a04903 | 284 | |
7f89ddce MD |
285 | if (!ctf_event) |
286 | return NULL; | |
287 | ||
288 | event = ctf_event->parent; | |
554cf424 | 289 | cfs = container_of(event->stream, const struct ctf_file_stream, |
98a04903 | 290 | parent); |
8b8dc96e | 291 | trace = cfs->parent.stream_class->trace; |
45807148 MD |
292 | if (trace->parent.ctx) |
293 | ret = trace->parent.ctx; | |
98a04903 JD |
294 | |
295 | return ret; | |
296 | } | |
297 | ||
c50d2a7a | 298 | int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event) |
98a04903 JD |
299 | { |
300 | int ret = -1; | |
554cf424 MD |
301 | const struct ctf_file_stream *cfs; |
302 | const struct ctf_trace *trace; | |
303 | const struct ctf_event_definition *event; | |
7f89ddce MD |
304 | |
305 | if (!ctf_event) | |
306 | return -EINVAL; | |
98a04903 | 307 | |
7f89ddce | 308 | event = ctf_event->parent; |
554cf424 | 309 | cfs = container_of(event->stream, const struct ctf_file_stream, |
98a04903 | 310 | parent); |
8b8dc96e | 311 | trace = cfs->parent.stream_class->trace; |
4d086981 MD |
312 | if (trace->parent.handle) |
313 | ret = trace->parent.handle->id; | |
98a04903 JD |
314 | |
315 | return ret; | |
316 | } | |
317 | ||
61cf588b | 318 | int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, int64_t *timestamp) |
9843982d | 319 | { |
554cf424 | 320 | const struct ctf_event_definition *event; |
7f89ddce | 321 | |
61cf588b MD |
322 | if (!ctf_event || !timestamp) |
323 | return -1; | |
7f89ddce MD |
324 | |
325 | event = ctf_event->parent; | |
9843982d | 326 | if (event && event->stream->has_timestamp) |
61cf588b | 327 | *timestamp = event->stream->real_timestamp; |
9843982d | 328 | else |
61cf588b MD |
329 | return -1; |
330 | return 0; | |
57f3005e SJD |
331 | } |
332 | ||
d40ee8ec | 333 | uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) |
57f3005e | 334 | { |
554cf424 | 335 | const struct ctf_event_definition *event; |
7f89ddce MD |
336 | |
337 | if (!ctf_event) | |
338 | return -1ULL; | |
339 | ||
340 | event = ctf_event->parent; | |
c34ea0fa | 341 | if (event && event->stream->has_timestamp) |
03798a93 | 342 | return event->stream->cycles_timestamp; |
c34ea0fa | 343 | else |
57f3005e | 344 | return -1ULL; |
9843982d JD |
345 | } |
346 | ||
347 | static void bt_ctf_field_set_error(int error) | |
348 | { | |
349 | bt_ctf_last_field_error = error; | |
350 | } | |
351 | ||
352 | int bt_ctf_field_get_error(void) | |
353 | { | |
354 | int ret; | |
355 | ret = bt_ctf_last_field_error; | |
356 | bt_ctf_last_field_error = 0; | |
357 | ||
358 | return ret; | |
359 | } | |
360 | ||
554cf424 | 361 | static const struct declaration_integer * |
ecc54f11 | 362 | get_declaration_integer(const struct bt_declaration *decl) |
2bdfa4cf | 363 | { |
554cf424 MD |
364 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_INTEGER) |
365 | return NULL; | |
366 | return container_of(decl, const struct declaration_integer, p); | |
2bdfa4cf JD |
367 | } |
368 | ||
554cf424 | 369 | static const struct declaration_string * |
ecc54f11 | 370 | get_declaration_string(const struct bt_declaration *decl) |
2bdfa4cf | 371 | { |
554cf424 MD |
372 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_STRING) |
373 | return NULL; | |
374 | return container_of(decl, const struct declaration_string, p); | |
2bdfa4cf JD |
375 | } |
376 | ||
554cf424 | 377 | static const struct declaration_array * |
ecc54f11 | 378 | get_declaration_array(const struct bt_declaration *decl) |
2bdfa4cf | 379 | { |
554cf424 MD |
380 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_ARRAY) |
381 | return NULL; | |
382 | return container_of(decl, const struct declaration_array, p); | |
2bdfa4cf JD |
383 | } |
384 | ||
c22b9327 | 385 | static const struct declaration_sequence * |
ecc54f11 | 386 | get_declaration_sequence(const struct bt_declaration *decl) |
c22b9327 JD |
387 | { |
388 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_SEQUENCE) | |
389 | return NULL; | |
390 | return container_of(decl, const struct declaration_sequence, p); | |
391 | } | |
392 | ||
ecc54f11 | 393 | int bt_ctf_get_int_signedness(const struct bt_declaration *decl) |
8673030f | 394 | { |
554cf424 | 395 | const struct declaration_integer *integer; |
8673030f | 396 | |
2bdfa4cf | 397 | integer = get_declaration_integer(decl); |
554cf424 | 398 | if (!integer) { |
8673030f | 399 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 400 | return -EINVAL; |
8673030f | 401 | } |
554cf424 | 402 | return integer->signedness; |
8673030f JD |
403 | } |
404 | ||
ecc54f11 | 405 | int bt_ctf_get_int_base(const struct bt_declaration *decl) |
8673030f | 406 | { |
554cf424 | 407 | const struct declaration_integer *integer; |
8673030f | 408 | |
2bdfa4cf | 409 | integer = get_declaration_integer(decl); |
554cf424 | 410 | if (!integer) { |
8673030f | 411 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 412 | return -EINVAL; |
8673030f | 413 | } |
554cf424 | 414 | return integer->base; |
8673030f JD |
415 | } |
416 | ||
ecc54f11 | 417 | int bt_ctf_get_int_byte_order(const struct bt_declaration *decl) |
8673030f | 418 | { |
554cf424 | 419 | const struct declaration_integer *integer; |
8673030f | 420 | |
2bdfa4cf | 421 | integer = get_declaration_integer(decl); |
554cf424 | 422 | if (!integer) { |
8673030f | 423 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 424 | return -EINVAL; |
8673030f | 425 | } |
554cf424 | 426 | return integer->byte_order; |
8673030f JD |
427 | } |
428 | ||
ecc54f11 | 429 | ssize_t bt_ctf_get_int_len(const struct bt_declaration *decl) |
fef0e521 | 430 | { |
554cf424 | 431 | const struct declaration_integer *integer; |
fef0e521 | 432 | |
2bdfa4cf | 433 | integer = get_declaration_integer(decl); |
554cf424 | 434 | if (!integer) { |
fef0e521 | 435 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 436 | return -EINVAL; |
fef0e521 | 437 | } |
554cf424 | 438 | return (ssize_t) integer->len; |
fef0e521 MD |
439 | } |
440 | ||
0d69b916 | 441 | const struct bt_definition *bt_ctf_get_enum_int(const struct bt_definition *field) |
4d25c350 | 442 | { |
554cf424 | 443 | const struct definition_enum *def_enum; |
4d25c350 | 444 | |
b14d90be | 445 | if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) { |
4d25c350 MD |
446 | bt_ctf_field_set_error(-EINVAL); |
447 | return NULL; | |
448 | } | |
554cf424 | 449 | def_enum = container_of(field, const struct definition_enum, p); |
4d25c350 MD |
450 | return &def_enum->integer->p; |
451 | } | |
452 | ||
0d69b916 | 453 | const char *bt_ctf_get_enum_str(const struct bt_definition *field) |
4d25c350 | 454 | { |
554cf424 MD |
455 | const struct definition_enum *def_enum; |
456 | const struct declaration_enum *decl_enum; | |
4d25c350 MD |
457 | GArray *array; |
458 | const char *ret; | |
459 | ||
b14d90be | 460 | if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) { |
4d25c350 MD |
461 | bt_ctf_field_set_error(-EINVAL); |
462 | return NULL; | |
463 | } | |
554cf424 | 464 | def_enum = container_of(field, const struct definition_enum, p); |
4d25c350 | 465 | decl_enum = def_enum->declaration; |
fe2b0e24 | 466 | if (bt_get_int_signedness(&def_enum->integer->p)) { |
2399b6f4 | 467 | array = bt_enum_int_to_quark_set(decl_enum, |
fe2b0e24 | 468 | bt_get_signed_int(&def_enum->integer->p)); |
4d25c350 | 469 | } else { |
2399b6f4 | 470 | array = bt_enum_uint_to_quark_set(decl_enum, |
fe2b0e24 | 471 | bt_get_unsigned_int(&def_enum->integer->p)); |
4d25c350 MD |
472 | } |
473 | if (!array) { | |
474 | bt_ctf_field_set_error(-ENOENT); | |
475 | return NULL; | |
476 | } | |
477 | ||
478 | if (array->len == 0) { | |
479 | g_array_unref(array); | |
480 | bt_ctf_field_set_error(-ENOENT); | |
481 | return NULL; | |
46df6b28 | 482 | } |
4d25c350 MD |
483 | /* Return first string. Arbitrary choice. */ |
484 | ret = g_quark_to_string(g_array_index(array, GQuark, 0)); | |
485 | g_array_unref(array); | |
486 | return ret; | |
487 | } | |
488 | ||
ecc54f11 | 489 | enum ctf_string_encoding bt_ctf_get_encoding(const struct bt_declaration *decl) |
8673030f JD |
490 | { |
491 | enum ctf_string_encoding ret = 0; | |
c22b9327 | 492 | enum ctf_type_id type; |
554cf424 MD |
493 | const struct declaration_integer *integer; |
494 | const struct declaration_string *string; | |
c22b9327 JD |
495 | const struct declaration_array *array; |
496 | const struct declaration_sequence *sequence; | |
8673030f | 497 | |
2bdfa4cf | 498 | if (!decl) |
7f89ddce | 499 | goto error; |
8673030f | 500 | |
c22b9327 JD |
501 | type = bt_ctf_field_type(decl); |
502 | ||
503 | switch (type) { | |
504 | case CTF_TYPE_ARRAY: | |
505 | array = get_declaration_array(decl); | |
506 | if (!array) | |
2bdfa4cf | 507 | goto error; |
c22b9327 JD |
508 | integer = get_declaration_integer(array->elem); |
509 | if (!integer) | |
510 | goto error; | |
511 | ret = integer->encoding; | |
512 | break; | |
513 | case CTF_TYPE_SEQUENCE: | |
514 | sequence = get_declaration_sequence(decl); | |
515 | if (!sequence) | |
516 | goto error; | |
517 | integer = get_declaration_integer(sequence->elem); | |
518 | if (!integer) | |
519 | goto error; | |
520 | ret = integer->encoding; | |
521 | break; | |
522 | case CTF_TYPE_STRING: | |
2bdfa4cf | 523 | string = get_declaration_string(decl); |
c22b9327 | 524 | if (!string) |
2bdfa4cf | 525 | goto error; |
c22b9327 JD |
526 | ret = string->encoding; |
527 | break; | |
528 | case CTF_TYPE_INTEGER: | |
529 | integer = get_declaration_integer(decl); | |
530 | if (!integer) | |
531 | goto error; | |
532 | ret = integer->encoding; | |
533 | break; | |
534 | default: | |
8673030f | 535 | goto error; |
2bdfa4cf | 536 | } |
8673030f JD |
537 | return ret; |
538 | ||
539 | error: | |
540 | bt_ctf_field_set_error(-EINVAL); | |
541 | return -1; | |
542 | } | |
543 | ||
ecc54f11 | 544 | int bt_ctf_get_array_len(const struct bt_declaration *decl) |
8673030f | 545 | { |
554cf424 | 546 | const struct declaration_array *array; |
8673030f | 547 | |
554cf424 MD |
548 | array = get_declaration_array(decl); |
549 | if (!array) | |
2bdfa4cf | 550 | goto error; |
554cf424 | 551 | return array->len; |
2bdfa4cf JD |
552 | |
553 | error: | |
554 | bt_ctf_field_set_error(-EINVAL); | |
555 | return -1; | |
8673030f JD |
556 | } |
557 | ||
0d69b916 | 558 | uint64_t bt_ctf_get_uint64(const struct bt_definition *field) |
9843982d | 559 | { |
63dd3817 | 560 | uint64_t ret = 0; |
9843982d | 561 | |
b14d90be | 562 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) |
fe2b0e24 | 563 | ret = bt_get_unsigned_int(field); |
9843982d JD |
564 | else |
565 | bt_ctf_field_set_error(-EINVAL); | |
566 | ||
567 | return ret; | |
568 | } | |
569 | ||
0d69b916 | 570 | int64_t bt_ctf_get_int64(const struct bt_definition *field) |
9843982d | 571 | { |
63dd3817 | 572 | int64_t ret = 0; |
9843982d | 573 | |
b14d90be | 574 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) |
fe2b0e24 | 575 | ret = bt_get_signed_int(field); |
9843982d JD |
576 | else |
577 | bt_ctf_field_set_error(-EINVAL); | |
578 | ||
579 | return ret; | |
9843982d JD |
580 | } |
581 | ||
0d69b916 | 582 | char *bt_ctf_get_char_array(const struct bt_definition *field) |
9843982d JD |
583 | { |
584 | char *ret = NULL; | |
885885bf | 585 | GString *char_array; |
9843982d | 586 | |
b14d90be | 587 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) { |
dcaa2e7d | 588 | char_array = bt_get_char_array(field); |
885885bf JD |
589 | if (char_array) { |
590 | ret = char_array->str; | |
591 | goto end; | |
592 | } | |
593 | } | |
594 | bt_ctf_field_set_error(-EINVAL); | |
9843982d | 595 | |
885885bf | 596 | end: |
9843982d JD |
597 | return ret; |
598 | } | |
599 | ||
0d69b916 | 600 | char *bt_ctf_get_string(const struct bt_definition *field) |
9843982d JD |
601 | { |
602 | char *ret = NULL; | |
603 | ||
b14d90be | 604 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING) |
ebdb2383 | 605 | ret = bt_get_string(field); |
9843982d JD |
606 | else |
607 | bt_ctf_field_set_error(-EINVAL); | |
608 | ||
609 | return ret; | |
610 | } | |
e003ab50 | 611 | |
e5a73b90 JG |
612 | double bt_ctf_get_float(const struct bt_definition *field) |
613 | { | |
614 | double ret = 0.0; | |
615 | ||
616 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_FLOAT) { | |
617 | ret = bt_get_float(field); | |
618 | } else { | |
619 | bt_ctf_field_set_error(-EINVAL); | |
620 | } | |
621 | ||
622 | return ret; | |
623 | } | |
624 | ||
812e6682 JG |
625 | const struct bt_definition *bt_ctf_get_variant(const struct bt_definition *field) |
626 | { | |
627 | const struct bt_definition *ret = NULL; | |
628 | ||
629 | if (field && bt_ctf_field_type( | |
630 | bt_ctf_get_decl_from_def(field)) == CTF_TYPE_VARIANT) { | |
631 | struct definition_variant *variant = container_of(field, | |
632 | struct definition_variant, p); | |
633 | ||
634 | ret = bt_variant_get_current_field(variant); | |
635 | } else { | |
636 | bt_ctf_field_set_error(-EINVAL); | |
637 | } | |
638 | ||
639 | return ret; | |
640 | } | |
3a068915 JG |
641 | |
642 | uint64_t bt_ctf_get_struct_field_count(const struct bt_definition *field) | |
643 | { | |
644 | uint64_t ret = -1; | |
645 | const struct bt_declaration *declaration = | |
646 | bt_ctf_get_decl_from_def(field); | |
647 | ||
648 | if (field && bt_ctf_field_type(declaration) == CTF_TYPE_STRUCT) { | |
649 | const struct declaration_struct *struct_declaration = | |
650 | container_of(declaration, struct declaration_struct, p); | |
651 | ||
652 | ret = bt_struct_declaration_len(struct_declaration); | |
812e6682 JG |
653 | } else { |
654 | bt_ctf_field_set_error(-EINVAL); | |
655 | } | |
656 | ||
657 | return ret; | |
658 | } | |
659 | ||
3a068915 JG |
660 | const struct bt_definition *bt_ctf_get_struct_field_index( |
661 | const struct bt_definition *field, uint64_t i) | |
662 | { | |
663 | const struct bt_definition *ret = NULL; | |
664 | ||
665 | if (field && bt_ctf_field_type( | |
666 | bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRUCT && | |
667 | i < bt_ctf_get_struct_field_count(field)) { | |
668 | const struct definition_struct *structure = container_of( | |
669 | field, struct definition_struct, p); | |
670 | ||
671 | ret = bt_struct_definition_get_field_from_index(structure, i); | |
672 | } | |
673 | ||
674 | if (!ret) { | |
675 | bt_ctf_field_set_error(-EINVAL); | |
676 | } | |
677 | ||
678 | return ret; | |
679 | } | |
680 | ||
e003ab50 | 681 | int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, |
64c2c249 | 682 | struct bt_ctf_event_decl * const **list, |
e003ab50 JD |
683 | unsigned int *count) |
684 | { | |
685 | struct bt_trace_handle *handle; | |
1b8455b7 | 686 | struct bt_trace_descriptor *td; |
e003ab50 JD |
687 | struct ctf_trace *tin; |
688 | ||
7f89ddce | 689 | if (!ctx || !list || !count) |
e003ab50 JD |
690 | goto error; |
691 | ||
692 | handle = g_hash_table_lookup(ctx->trace_handles, | |
5b44aff2 | 693 | GUINT_TO_POINTER(handle_id)); |
e003ab50 JD |
694 | if (!handle) |
695 | goto error; | |
696 | ||
697 | td = handle->td; | |
698 | tin = container_of(td, struct ctf_trace, parent); | |
699 | ||
64c2c249 | 700 | *list = (struct bt_ctf_event_decl * const*) tin->event_declarations->pdata; |
e003ab50 JD |
701 | *count = tin->event_declarations->len; |
702 | return 0; | |
703 | ||
704 | error: | |
705 | return -1; | |
706 | } | |
707 | ||
708 | const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event) | |
709 | { | |
710 | if (!event) | |
711 | return NULL; | |
7f89ddce | 712 | |
e003ab50 JD |
713 | return g_quark_to_string(event->parent.name); |
714 | } | |
64c2c249 | 715 | |
78564612 AM |
716 | uint64_t bt_ctf_get_decl_event_id(const struct bt_ctf_event_decl *event) |
717 | { | |
718 | if (!event) | |
719 | return (uint64_t)(-1); | |
720 | ||
721 | return event->parent.id; | |
722 | } | |
723 | ||
64c2c249 | 724 | int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl, |
46df6b28 | 725 | enum ctf_scope scope, |
64c2c249 JD |
726 | struct bt_ctf_field_decl const * const **list, |
727 | unsigned int *count) | |
728 | { | |
729 | int i; | |
730 | GArray *fields = NULL; | |
731 | gpointer *ret_list = NULL; | |
732 | GPtrArray *fields_array = NULL; | |
733 | int ret = 0; | |
64c2c249 | 734 | |
7f89ddce MD |
735 | if (!event_decl || !list || !count) |
736 | return -EINVAL; | |
737 | ||
3b7335c3 | 738 | *count = 0; |
64c2c249 JD |
739 | switch (scope) { |
740 | case BT_EVENT_CONTEXT: | |
741 | if (event_decl->context_decl) { | |
742 | ret_list = event_decl->context_decl->pdata; | |
743 | *count = event_decl->context_decl->len; | |
744 | goto end; | |
745 | } | |
746 | event_decl->context_decl = g_ptr_array_new(); | |
747 | if (!event_decl->parent.context_decl) { | |
748 | ret = -1; | |
749 | goto end; | |
750 | } | |
751 | fields = event_decl->parent.context_decl->fields; | |
752 | fields_array = event_decl->context_decl; | |
753 | break; | |
754 | case BT_EVENT_FIELDS: | |
755 | if (event_decl->fields_decl) { | |
756 | ret_list = event_decl->fields_decl->pdata; | |
757 | *count = event_decl->fields_decl->len; | |
758 | goto end; | |
759 | } | |
760 | event_decl->fields_decl = g_ptr_array_new(); | |
761 | if (!event_decl->parent.fields_decl) { | |
762 | ret = -1; | |
763 | goto end; | |
764 | } | |
765 | fields = event_decl->parent.fields_decl->fields; | |
766 | fields_array = event_decl->fields_decl; | |
767 | break; | |
768 | case BT_STREAM_PACKET_CONTEXT: | |
769 | if (event_decl->packet_context_decl) { | |
770 | ret_list = event_decl->packet_context_decl->pdata; | |
771 | *count = event_decl->packet_context_decl->len; | |
772 | goto end; | |
773 | } | |
774 | event_decl->packet_context_decl = g_ptr_array_new(); | |
775 | if (!event_decl->parent.stream->packet_context_decl) { | |
776 | ret = -1; | |
777 | goto end; | |
778 | } | |
779 | fields = event_decl->parent.stream->packet_context_decl->fields; | |
780 | fields_array = event_decl->packet_context_decl; | |
781 | break; | |
782 | case BT_STREAM_EVENT_CONTEXT: | |
783 | if (event_decl->event_context_decl) { | |
784 | ret_list = event_decl->event_context_decl->pdata; | |
785 | *count = event_decl->event_context_decl->len; | |
786 | goto end; | |
787 | } | |
788 | event_decl->event_context_decl = g_ptr_array_new(); | |
789 | if (!event_decl->parent.stream->event_context_decl) { | |
790 | ret = -1; | |
791 | goto end; | |
792 | } | |
793 | fields = event_decl->parent.stream->event_context_decl->fields; | |
794 | fields_array = event_decl->event_context_decl; | |
795 | break; | |
796 | case BT_STREAM_EVENT_HEADER: | |
797 | if (event_decl->event_header_decl) { | |
798 | ret_list = event_decl->event_header_decl->pdata; | |
799 | *count = event_decl->event_header_decl->len; | |
800 | goto end; | |
801 | } | |
802 | event_decl->event_header_decl = g_ptr_array_new(); | |
803 | if (!event_decl->parent.stream->event_header_decl) { | |
804 | ret = -1; | |
805 | goto end; | |
806 | } | |
807 | fields = event_decl->parent.stream->event_header_decl->fields; | |
808 | fields_array = event_decl->event_header_decl; | |
809 | break; | |
810 | case BT_TRACE_PACKET_HEADER: | |
811 | if (event_decl->packet_header_decl) { | |
812 | ret_list = event_decl->packet_header_decl->pdata; | |
813 | *count = event_decl->packet_header_decl->len; | |
814 | goto end; | |
815 | } | |
816 | event_decl->packet_header_decl = g_ptr_array_new(); | |
817 | if (!event_decl->parent.stream->trace->packet_header_decl) { | |
818 | ret = -1; | |
819 | goto end; | |
820 | } | |
821 | fields = event_decl->parent.stream->trace->packet_header_decl->fields; | |
822 | fields_array = event_decl->packet_header_decl; | |
823 | break; | |
824 | } | |
825 | ||
826 | for (i = 0; i < fields->len; i++) { | |
827 | g_ptr_array_add(fields_array, | |
828 | &g_array_index(fields, | |
829 | struct declaration_field, i)); | |
830 | } | |
831 | ret_list = fields_array->pdata; | |
832 | *count = fields->len; | |
833 | ||
834 | end: | |
835 | *list = (struct bt_ctf_field_decl const* const*) ret_list; | |
836 | ||
837 | return ret; | |
838 | } | |
839 | ||
840 | const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field) | |
841 | { | |
7f89ddce MD |
842 | if (!field) |
843 | return NULL; | |
844 | ||
845 | return rem_(g_quark_to_string(((struct declaration_field *) field)->name)); | |
64c2c249 | 846 | } |
2bdfa4cf | 847 | |
ecc54f11 | 848 | const struct bt_declaration *bt_ctf_get_decl_from_def(const struct bt_definition *def) |
2bdfa4cf JD |
849 | { |
850 | if (def) | |
851 | return def->declaration; | |
852 | ||
853 | return NULL; | |
854 | } | |
b14d90be | 855 | |
ecc54f11 | 856 | const struct bt_declaration *bt_ctf_get_decl_from_field_decl( |
b14d90be JD |
857 | const struct bt_ctf_field_decl *field) |
858 | { | |
859 | if (field) | |
860 | return ((struct declaration_field *) field)->declaration; | |
861 | ||
862 | return NULL; | |
863 | } |