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, |
9843982d JD |
50 | enum bt_ctf_scope scope) |
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; |
9843982d JD |
258 | *count = def_sequence->elems->len; |
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 | ||
d40ee8ec | 318 | uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event) |
9843982d | 319 | { |
554cf424 | 320 | const struct ctf_event_definition *event; |
7f89ddce MD |
321 | |
322 | if (!ctf_event) | |
323 | return -1ULL; | |
324 | ||
325 | event = ctf_event->parent; | |
9843982d | 326 | if (event && event->stream->has_timestamp) |
03798a93 | 327 | return event->stream->real_timestamp; |
9843982d | 328 | else |
57f3005e SJD |
329 | return -1ULL; |
330 | } | |
331 | ||
d40ee8ec | 332 | uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event) |
57f3005e | 333 | { |
554cf424 | 334 | const struct ctf_event_definition *event; |
7f89ddce MD |
335 | |
336 | if (!ctf_event) | |
337 | return -1ULL; | |
338 | ||
339 | event = ctf_event->parent; | |
c34ea0fa | 340 | if (event && event->stream->has_timestamp) |
03798a93 | 341 | return event->stream->cycles_timestamp; |
c34ea0fa | 342 | else |
57f3005e | 343 | return -1ULL; |
9843982d JD |
344 | } |
345 | ||
346 | static void bt_ctf_field_set_error(int error) | |
347 | { | |
348 | bt_ctf_last_field_error = error; | |
349 | } | |
350 | ||
351 | int bt_ctf_field_get_error(void) | |
352 | { | |
353 | int ret; | |
354 | ret = bt_ctf_last_field_error; | |
355 | bt_ctf_last_field_error = 0; | |
356 | ||
357 | return ret; | |
358 | } | |
359 | ||
554cf424 | 360 | static const struct declaration_integer * |
ecc54f11 | 361 | get_declaration_integer(const struct bt_declaration *decl) |
2bdfa4cf | 362 | { |
554cf424 MD |
363 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_INTEGER) |
364 | return NULL; | |
365 | return container_of(decl, const struct declaration_integer, p); | |
2bdfa4cf JD |
366 | } |
367 | ||
554cf424 | 368 | static const struct declaration_string * |
ecc54f11 | 369 | get_declaration_string(const struct bt_declaration *decl) |
2bdfa4cf | 370 | { |
554cf424 MD |
371 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_STRING) |
372 | return NULL; | |
373 | return container_of(decl, const struct declaration_string, p); | |
2bdfa4cf JD |
374 | } |
375 | ||
554cf424 | 376 | static const struct declaration_array * |
ecc54f11 | 377 | get_declaration_array(const struct bt_declaration *decl) |
2bdfa4cf | 378 | { |
554cf424 MD |
379 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_ARRAY) |
380 | return NULL; | |
381 | return container_of(decl, const struct declaration_array, p); | |
2bdfa4cf JD |
382 | } |
383 | ||
c22b9327 | 384 | static const struct declaration_sequence * |
ecc54f11 | 385 | get_declaration_sequence(const struct bt_declaration *decl) |
c22b9327 JD |
386 | { |
387 | if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_SEQUENCE) | |
388 | return NULL; | |
389 | return container_of(decl, const struct declaration_sequence, p); | |
390 | } | |
391 | ||
ecc54f11 | 392 | int bt_ctf_get_int_signedness(const struct bt_declaration *decl) |
8673030f | 393 | { |
554cf424 | 394 | const struct declaration_integer *integer; |
8673030f | 395 | |
2bdfa4cf | 396 | integer = get_declaration_integer(decl); |
554cf424 | 397 | if (!integer) { |
8673030f | 398 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 399 | return -EINVAL; |
8673030f | 400 | } |
554cf424 | 401 | return integer->signedness; |
8673030f JD |
402 | } |
403 | ||
ecc54f11 | 404 | int bt_ctf_get_int_base(const struct bt_declaration *decl) |
8673030f | 405 | { |
554cf424 | 406 | const struct declaration_integer *integer; |
8673030f | 407 | |
2bdfa4cf | 408 | integer = get_declaration_integer(decl); |
554cf424 | 409 | if (!integer) { |
8673030f | 410 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 411 | return -EINVAL; |
8673030f | 412 | } |
554cf424 | 413 | return integer->base; |
8673030f JD |
414 | } |
415 | ||
ecc54f11 | 416 | int bt_ctf_get_int_byte_order(const struct bt_declaration *decl) |
8673030f | 417 | { |
554cf424 | 418 | const struct declaration_integer *integer; |
8673030f | 419 | |
2bdfa4cf | 420 | integer = get_declaration_integer(decl); |
554cf424 | 421 | if (!integer) { |
8673030f | 422 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 423 | return -EINVAL; |
8673030f | 424 | } |
554cf424 | 425 | return integer->byte_order; |
8673030f JD |
426 | } |
427 | ||
ecc54f11 | 428 | ssize_t bt_ctf_get_int_len(const struct bt_declaration *decl) |
fef0e521 | 429 | { |
554cf424 | 430 | const struct declaration_integer *integer; |
fef0e521 | 431 | |
2bdfa4cf | 432 | integer = get_declaration_integer(decl); |
554cf424 | 433 | if (!integer) { |
fef0e521 | 434 | bt_ctf_field_set_error(-EINVAL); |
554cf424 | 435 | return -EINVAL; |
fef0e521 | 436 | } |
554cf424 | 437 | return (ssize_t) integer->len; |
fef0e521 MD |
438 | } |
439 | ||
0d69b916 | 440 | const struct bt_definition *bt_ctf_get_enum_int(const struct bt_definition *field) |
4d25c350 | 441 | { |
554cf424 | 442 | const struct definition_enum *def_enum; |
4d25c350 | 443 | |
b14d90be | 444 | if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) { |
4d25c350 MD |
445 | bt_ctf_field_set_error(-EINVAL); |
446 | return NULL; | |
447 | } | |
554cf424 | 448 | def_enum = container_of(field, const struct definition_enum, p); |
4d25c350 MD |
449 | return &def_enum->integer->p; |
450 | } | |
451 | ||
0d69b916 | 452 | const char *bt_ctf_get_enum_str(const struct bt_definition *field) |
4d25c350 | 453 | { |
554cf424 MD |
454 | const struct definition_enum *def_enum; |
455 | const struct declaration_enum *decl_enum; | |
4d25c350 MD |
456 | GArray *array; |
457 | const char *ret; | |
458 | ||
b14d90be | 459 | if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) { |
4d25c350 MD |
460 | bt_ctf_field_set_error(-EINVAL); |
461 | return NULL; | |
462 | } | |
554cf424 | 463 | def_enum = container_of(field, const struct definition_enum, p); |
4d25c350 | 464 | decl_enum = def_enum->declaration; |
fe2b0e24 | 465 | if (bt_get_int_signedness(&def_enum->integer->p)) { |
2399b6f4 | 466 | array = bt_enum_int_to_quark_set(decl_enum, |
fe2b0e24 | 467 | bt_get_signed_int(&def_enum->integer->p)); |
4d25c350 | 468 | } else { |
2399b6f4 | 469 | array = bt_enum_uint_to_quark_set(decl_enum, |
fe2b0e24 | 470 | bt_get_unsigned_int(&def_enum->integer->p)); |
4d25c350 MD |
471 | } |
472 | if (!array) { | |
473 | bt_ctf_field_set_error(-ENOENT); | |
474 | return NULL; | |
475 | } | |
476 | ||
477 | if (array->len == 0) { | |
478 | g_array_unref(array); | |
479 | bt_ctf_field_set_error(-ENOENT); | |
480 | return NULL; | |
481 | } | |
482 | /* Return first string. Arbitrary choice. */ | |
483 | ret = g_quark_to_string(g_array_index(array, GQuark, 0)); | |
484 | g_array_unref(array); | |
485 | return ret; | |
486 | } | |
487 | ||
ecc54f11 | 488 | enum ctf_string_encoding bt_ctf_get_encoding(const struct bt_declaration *decl) |
8673030f JD |
489 | { |
490 | enum ctf_string_encoding ret = 0; | |
c22b9327 | 491 | enum ctf_type_id type; |
554cf424 MD |
492 | const struct declaration_integer *integer; |
493 | const struct declaration_string *string; | |
c22b9327 JD |
494 | const struct declaration_array *array; |
495 | const struct declaration_sequence *sequence; | |
8673030f | 496 | |
2bdfa4cf | 497 | if (!decl) |
7f89ddce | 498 | goto error; |
8673030f | 499 | |
c22b9327 JD |
500 | type = bt_ctf_field_type(decl); |
501 | ||
502 | switch (type) { | |
503 | case CTF_TYPE_ARRAY: | |
504 | array = get_declaration_array(decl); | |
505 | if (!array) | |
2bdfa4cf | 506 | goto error; |
c22b9327 JD |
507 | integer = get_declaration_integer(array->elem); |
508 | if (!integer) | |
509 | goto error; | |
510 | ret = integer->encoding; | |
511 | break; | |
512 | case CTF_TYPE_SEQUENCE: | |
513 | sequence = get_declaration_sequence(decl); | |
514 | if (!sequence) | |
515 | goto error; | |
516 | integer = get_declaration_integer(sequence->elem); | |
517 | if (!integer) | |
518 | goto error; | |
519 | ret = integer->encoding; | |
520 | break; | |
521 | case CTF_TYPE_STRING: | |
2bdfa4cf | 522 | string = get_declaration_string(decl); |
c22b9327 | 523 | if (!string) |
2bdfa4cf | 524 | goto error; |
c22b9327 JD |
525 | ret = string->encoding; |
526 | break; | |
527 | case CTF_TYPE_INTEGER: | |
528 | integer = get_declaration_integer(decl); | |
529 | if (!integer) | |
530 | goto error; | |
531 | ret = integer->encoding; | |
532 | break; | |
533 | default: | |
8673030f | 534 | goto error; |
2bdfa4cf | 535 | } |
8673030f JD |
536 | return ret; |
537 | ||
538 | error: | |
539 | bt_ctf_field_set_error(-EINVAL); | |
540 | return -1; | |
541 | } | |
542 | ||
ecc54f11 | 543 | int bt_ctf_get_array_len(const struct bt_declaration *decl) |
8673030f | 544 | { |
554cf424 | 545 | const struct declaration_array *array; |
8673030f | 546 | |
554cf424 MD |
547 | array = get_declaration_array(decl); |
548 | if (!array) | |
2bdfa4cf | 549 | goto error; |
554cf424 | 550 | return array->len; |
2bdfa4cf JD |
551 | |
552 | error: | |
553 | bt_ctf_field_set_error(-EINVAL); | |
554 | return -1; | |
8673030f JD |
555 | } |
556 | ||
0d69b916 | 557 | uint64_t bt_ctf_get_uint64(const struct bt_definition *field) |
9843982d | 558 | { |
63dd3817 | 559 | uint64_t ret = 0; |
9843982d | 560 | |
b14d90be | 561 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) |
fe2b0e24 | 562 | ret = bt_get_unsigned_int(field); |
9843982d JD |
563 | else |
564 | bt_ctf_field_set_error(-EINVAL); | |
565 | ||
566 | return ret; | |
567 | } | |
568 | ||
0d69b916 | 569 | int64_t bt_ctf_get_int64(const struct bt_definition *field) |
9843982d | 570 | { |
63dd3817 | 571 | int64_t ret = 0; |
9843982d | 572 | |
b14d90be | 573 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) |
fe2b0e24 | 574 | ret = bt_get_signed_int(field); |
9843982d JD |
575 | else |
576 | bt_ctf_field_set_error(-EINVAL); | |
577 | ||
578 | return ret; | |
9843982d JD |
579 | } |
580 | ||
0d69b916 | 581 | char *bt_ctf_get_char_array(const struct bt_definition *field) |
9843982d JD |
582 | { |
583 | char *ret = NULL; | |
885885bf | 584 | GString *char_array; |
9843982d | 585 | |
b14d90be | 586 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) { |
dcaa2e7d | 587 | char_array = bt_get_char_array(field); |
885885bf JD |
588 | if (char_array) { |
589 | ret = char_array->str; | |
590 | goto end; | |
591 | } | |
592 | } | |
593 | bt_ctf_field_set_error(-EINVAL); | |
9843982d | 594 | |
885885bf | 595 | end: |
9843982d JD |
596 | return ret; |
597 | } | |
598 | ||
0d69b916 | 599 | char *bt_ctf_get_string(const struct bt_definition *field) |
9843982d JD |
600 | { |
601 | char *ret = NULL; | |
602 | ||
b14d90be | 603 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING) |
ebdb2383 | 604 | ret = bt_get_string(field); |
9843982d JD |
605 | else |
606 | bt_ctf_field_set_error(-EINVAL); | |
607 | ||
608 | return ret; | |
609 | } | |
e003ab50 | 610 | |
e5a73b90 JG |
611 | double bt_ctf_get_float(const struct bt_definition *field) |
612 | { | |
613 | double ret = 0.0; | |
614 | ||
615 | if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_FLOAT) { | |
616 | ret = bt_get_float(field); | |
617 | } else { | |
618 | bt_ctf_field_set_error(-EINVAL); | |
619 | } | |
620 | ||
621 | return ret; | |
622 | } | |
623 | ||
812e6682 JG |
624 | const struct bt_definition *bt_ctf_get_variant(const struct bt_definition *field) |
625 | { | |
626 | const struct bt_definition *ret = NULL; | |
627 | ||
628 | if (field && bt_ctf_field_type( | |
629 | bt_ctf_get_decl_from_def(field)) == CTF_TYPE_VARIANT) { | |
630 | struct definition_variant *variant = container_of(field, | |
631 | struct definition_variant, p); | |
632 | ||
633 | ret = bt_variant_get_current_field(variant); | |
634 | } else { | |
635 | bt_ctf_field_set_error(-EINVAL); | |
636 | } | |
637 | ||
638 | return ret; | |
639 | } | |
3a068915 JG |
640 | |
641 | uint64_t bt_ctf_get_struct_field_count(const struct bt_definition *field) | |
642 | { | |
643 | uint64_t ret = -1; | |
644 | const struct bt_declaration *declaration = | |
645 | bt_ctf_get_decl_from_def(field); | |
646 | ||
647 | if (field && bt_ctf_field_type(declaration) == CTF_TYPE_STRUCT) { | |
648 | const struct declaration_struct *struct_declaration = | |
649 | container_of(declaration, struct declaration_struct, p); | |
650 | ||
651 | ret = bt_struct_declaration_len(struct_declaration); | |
812e6682 JG |
652 | } else { |
653 | bt_ctf_field_set_error(-EINVAL); | |
654 | } | |
655 | ||
656 | return ret; | |
657 | } | |
658 | ||
3a068915 JG |
659 | const struct bt_definition *bt_ctf_get_struct_field_index( |
660 | const struct bt_definition *field, uint64_t i) | |
661 | { | |
662 | const struct bt_definition *ret = NULL; | |
663 | ||
664 | if (field && bt_ctf_field_type( | |
665 | bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRUCT && | |
666 | i < bt_ctf_get_struct_field_count(field)) { | |
667 | const struct definition_struct *structure = container_of( | |
668 | field, struct definition_struct, p); | |
669 | ||
670 | ret = bt_struct_definition_get_field_from_index(structure, i); | |
671 | } | |
672 | ||
673 | if (!ret) { | |
674 | bt_ctf_field_set_error(-EINVAL); | |
675 | } | |
676 | ||
677 | return ret; | |
678 | } | |
679 | ||
e003ab50 | 680 | int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, |
64c2c249 | 681 | struct bt_ctf_event_decl * const **list, |
e003ab50 JD |
682 | unsigned int *count) |
683 | { | |
684 | struct bt_trace_handle *handle; | |
1b8455b7 | 685 | struct bt_trace_descriptor *td; |
e003ab50 JD |
686 | struct ctf_trace *tin; |
687 | ||
7f89ddce | 688 | if (!ctx || !list || !count) |
e003ab50 JD |
689 | goto error; |
690 | ||
691 | handle = g_hash_table_lookup(ctx->trace_handles, | |
692 | (gpointer) (unsigned long) handle_id); | |
693 | if (!handle) | |
694 | goto error; | |
695 | ||
696 | td = handle->td; | |
697 | tin = container_of(td, struct ctf_trace, parent); | |
698 | ||
64c2c249 | 699 | *list = (struct bt_ctf_event_decl * const*) tin->event_declarations->pdata; |
e003ab50 JD |
700 | *count = tin->event_declarations->len; |
701 | return 0; | |
702 | ||
703 | error: | |
704 | return -1; | |
705 | } | |
706 | ||
707 | const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event) | |
708 | { | |
709 | if (!event) | |
710 | return NULL; | |
7f89ddce | 711 | |
e003ab50 JD |
712 | return g_quark_to_string(event->parent.name); |
713 | } | |
64c2c249 JD |
714 | |
715 | int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl, | |
716 | enum bt_ctf_scope scope, | |
717 | struct bt_ctf_field_decl const * const **list, | |
718 | unsigned int *count) | |
719 | { | |
720 | int i; | |
721 | GArray *fields = NULL; | |
722 | gpointer *ret_list = NULL; | |
723 | GPtrArray *fields_array = NULL; | |
724 | int ret = 0; | |
64c2c249 | 725 | |
7f89ddce MD |
726 | if (!event_decl || !list || !count) |
727 | return -EINVAL; | |
728 | ||
3b7335c3 | 729 | *count = 0; |
64c2c249 JD |
730 | switch (scope) { |
731 | case BT_EVENT_CONTEXT: | |
732 | if (event_decl->context_decl) { | |
733 | ret_list = event_decl->context_decl->pdata; | |
734 | *count = event_decl->context_decl->len; | |
735 | goto end; | |
736 | } | |
737 | event_decl->context_decl = g_ptr_array_new(); | |
738 | if (!event_decl->parent.context_decl) { | |
739 | ret = -1; | |
740 | goto end; | |
741 | } | |
742 | fields = event_decl->parent.context_decl->fields; | |
743 | fields_array = event_decl->context_decl; | |
744 | break; | |
745 | case BT_EVENT_FIELDS: | |
746 | if (event_decl->fields_decl) { | |
747 | ret_list = event_decl->fields_decl->pdata; | |
748 | *count = event_decl->fields_decl->len; | |
749 | goto end; | |
750 | } | |
751 | event_decl->fields_decl = g_ptr_array_new(); | |
752 | if (!event_decl->parent.fields_decl) { | |
753 | ret = -1; | |
754 | goto end; | |
755 | } | |
756 | fields = event_decl->parent.fields_decl->fields; | |
757 | fields_array = event_decl->fields_decl; | |
758 | break; | |
759 | case BT_STREAM_PACKET_CONTEXT: | |
760 | if (event_decl->packet_context_decl) { | |
761 | ret_list = event_decl->packet_context_decl->pdata; | |
762 | *count = event_decl->packet_context_decl->len; | |
763 | goto end; | |
764 | } | |
765 | event_decl->packet_context_decl = g_ptr_array_new(); | |
766 | if (!event_decl->parent.stream->packet_context_decl) { | |
767 | ret = -1; | |
768 | goto end; | |
769 | } | |
770 | fields = event_decl->parent.stream->packet_context_decl->fields; | |
771 | fields_array = event_decl->packet_context_decl; | |
772 | break; | |
773 | case BT_STREAM_EVENT_CONTEXT: | |
774 | if (event_decl->event_context_decl) { | |
775 | ret_list = event_decl->event_context_decl->pdata; | |
776 | *count = event_decl->event_context_decl->len; | |
777 | goto end; | |
778 | } | |
779 | event_decl->event_context_decl = g_ptr_array_new(); | |
780 | if (!event_decl->parent.stream->event_context_decl) { | |
781 | ret = -1; | |
782 | goto end; | |
783 | } | |
784 | fields = event_decl->parent.stream->event_context_decl->fields; | |
785 | fields_array = event_decl->event_context_decl; | |
786 | break; | |
787 | case BT_STREAM_EVENT_HEADER: | |
788 | if (event_decl->event_header_decl) { | |
789 | ret_list = event_decl->event_header_decl->pdata; | |
790 | *count = event_decl->event_header_decl->len; | |
791 | goto end; | |
792 | } | |
793 | event_decl->event_header_decl = g_ptr_array_new(); | |
794 | if (!event_decl->parent.stream->event_header_decl) { | |
795 | ret = -1; | |
796 | goto end; | |
797 | } | |
798 | fields = event_decl->parent.stream->event_header_decl->fields; | |
799 | fields_array = event_decl->event_header_decl; | |
800 | break; | |
801 | case BT_TRACE_PACKET_HEADER: | |
802 | if (event_decl->packet_header_decl) { | |
803 | ret_list = event_decl->packet_header_decl->pdata; | |
804 | *count = event_decl->packet_header_decl->len; | |
805 | goto end; | |
806 | } | |
807 | event_decl->packet_header_decl = g_ptr_array_new(); | |
808 | if (!event_decl->parent.stream->trace->packet_header_decl) { | |
809 | ret = -1; | |
810 | goto end; | |
811 | } | |
812 | fields = event_decl->parent.stream->trace->packet_header_decl->fields; | |
813 | fields_array = event_decl->packet_header_decl; | |
814 | break; | |
815 | } | |
816 | ||
817 | for (i = 0; i < fields->len; i++) { | |
818 | g_ptr_array_add(fields_array, | |
819 | &g_array_index(fields, | |
820 | struct declaration_field, i)); | |
821 | } | |
822 | ret_list = fields_array->pdata; | |
823 | *count = fields->len; | |
824 | ||
825 | end: | |
826 | *list = (struct bt_ctf_field_decl const* const*) ret_list; | |
827 | ||
828 | return ret; | |
829 | } | |
830 | ||
831 | const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field) | |
832 | { | |
7f89ddce MD |
833 | if (!field) |
834 | return NULL; | |
835 | ||
836 | return rem_(g_quark_to_string(((struct declaration_field *) field)->name)); | |
64c2c249 | 837 | } |
2bdfa4cf | 838 | |
ecc54f11 | 839 | const struct bt_declaration *bt_ctf_get_decl_from_def(const struct bt_definition *def) |
2bdfa4cf JD |
840 | { |
841 | if (def) | |
842 | return def->declaration; | |
843 | ||
844 | return NULL; | |
845 | } | |
b14d90be | 846 | |
ecc54f11 | 847 | const struct bt_declaration *bt_ctf_get_decl_from_field_decl( |
b14d90be JD |
848 | const struct bt_ctf_field_decl *field) |
849 | { | |
850 | if (field) | |
851 | return ((struct declaration_field *) field)->declaration; | |
852 | ||
853 | return NULL; | |
854 | } |