1 /*
2  * ctf/events.c
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.
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.
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>
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>
38 #include <glib.h>
39 
40 #include "events-private.h"
41 
42 /*
43  * thread local storage to store the last error that occured
44  * while reading a field, this variable must be accessed by
45  * bt_ctf_field_get_error only
46  */
47 __thread int bt_ctf_last_field_error = 0;
48 
bt_ctf_get_top_level_scope(const struct bt_ctf_event * ctf_event,enum bt_ctf_scope scope)49 const struct bt_definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event,
50 		enum bt_ctf_scope scope)
51 {
52 	const struct bt_definition *tmp = NULL;
53 	const struct ctf_event_definition *event;
54 
55 	if (!ctf_event)
56 		return NULL;
57 
58 	event = ctf_event->parent;
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:
85 		if (event->event_context)
86 			tmp = &event->event_context->p;
87 		break;
88 	case BT_EVENT_FIELDS:
89 		if (event->event_fields)
90 			tmp = &event->event_fields->p;
91 		break;
92 	}
93 	return tmp;
94 
95 error:
96 	return NULL;
97 }
98 
bt_ctf_get_field(const struct bt_ctf_event * ctf_event,const struct bt_definition * scope,const char * field)99 const struct bt_definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
100 		const struct bt_definition *scope,
101 		const char *field)
102 {
103 	const struct bt_definition *def;
104 	char *field_underscore;
105 
106 	if (!ctf_event || !scope || !field)
107 		return NULL;
108 
109 	def = bt_lookup_definition(scope, field);
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);
118 		def = bt_lookup_definition(scope, field_underscore);
119 		g_free(field_underscore);
120 	}
121 	if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def)) == CTF_TYPE_VARIANT) {
122 		const struct definition_variant *variant_definition;
123 		variant_definition = container_of(def,
124 				const struct definition_variant, p);
125 		return variant_definition->current_field;
126 	}
127 	return def;
128 }
129 
bt_ctf_get_index(const struct bt_ctf_event * ctf_event,const struct bt_definition * field,unsigned int index)130 const struct bt_definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event,
131 		const struct bt_definition *field,
132 		unsigned int index)
133 {
134 	struct bt_definition *ret = NULL;
135 
136 	if (!ctf_event || !field)
137 		return NULL;
138 
139 	if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) {
140 		struct definition_array *array_definition;
141 		array_definition = container_of(field,
142 				struct definition_array, p);
143 		ret = bt_array_index(array_definition, index);
144 	} else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_SEQUENCE) {
145 		struct definition_sequence *sequence_definition;
146 		sequence_definition = container_of(field,
147 				struct definition_sequence, p);
148 		ret = bt_sequence_index(sequence_definition, index);
149 	}
150 	return ret;
151 }
152 
bt_ctf_event_name(const struct bt_ctf_event * ctf_event)153 const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event)
154 {
155 	const struct ctf_event_declaration *event_class;
156 	const struct ctf_stream_declaration *stream_class;
157 	const struct ctf_event_definition *event;
158 
159 	if (!ctf_event)
160 		return NULL;
161 
162 	event = ctf_event->parent;
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 
bt_ctf_field_name(const struct bt_definition * def)169 const char *bt_ctf_field_name(const struct bt_definition *def)
170 {
171 	if (!def || !def->name)
172 		return NULL;
173 
174 	return rem_(g_quark_to_string(def->name));
175 }
176 
bt_ctf_field_type(const struct bt_declaration * decl)177 enum ctf_type_id bt_ctf_field_type(const struct bt_declaration *decl)
178 {
179 	if (!decl)
180 		return CTF_TYPE_UNKNOWN;
181 
182 	return decl->id;
183 }
184 
bt_ctf_get_field_list(const struct bt_ctf_event * ctf_event,const struct bt_definition * scope,struct bt_definition const * const ** list,unsigned int * count)185 int bt_ctf_get_field_list(const struct bt_ctf_event *ctf_event,
186 		const struct bt_definition *scope,
187 		struct bt_definition const * const **list,
188 		unsigned int *count)
189 {
190 	if (!ctf_event || !scope || !list || !count)
191 		return -EINVAL;
192 
193 	switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope))) {
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 	{
201 		const struct definition_struct *def_struct;
202 
203 		def_struct = container_of(scope, const struct definition_struct, p);
204 		if (!def_struct)
205 			goto error;
206 		if (def_struct->fields->pdata) {
207 			*list = (struct bt_definition const* const*) def_struct->fields->pdata;
208 			*count = def_struct->fields->len;
209 			goto end;
210 		} else {
211 			goto error;
212 		}
213 		break;
214 	}
215 	case CTF_TYPE_UNTAGGED_VARIANT:
216 		goto error;
217 	case CTF_TYPE_VARIANT:
218 	{
219 		const struct definition_variant *def_variant;
220 
221 		def_variant = container_of(scope, const struct definition_variant, p);
222 		if (!def_variant)
223 			goto error;
224 		if (def_variant->fields->pdata) {
225 			*list = (struct bt_definition const* const*) def_variant->fields->pdata;
226 			*count = def_variant->fields->len;
227 			goto end;
228 		} else {
229 			goto error;
230 		}
231 		break;
232 	}
233 	case CTF_TYPE_ARRAY:
234 	{
235 		const struct definition_array *def_array;
236 
237 		def_array = container_of(scope, const struct definition_array, p);
238 		if (!def_array)
239 			goto error;
240 		if (def_array->elems->pdata) {
241 			*list = (struct bt_definition const* const*) def_array->elems->pdata;
242 			*count = def_array->elems->len;
243 			goto end;
244 		} else {
245 			goto error;
246 		}
247 		break;
248 	}
249 	case CTF_TYPE_SEQUENCE:
250 	{
251 		const struct definition_sequence *def_sequence;
252 
253 		def_sequence = container_of(scope, const struct definition_sequence, p);
254 		if (!def_sequence)
255 			goto error;
256 		if (def_sequence->elems->pdata) {
257 			*list = (struct bt_definition const* const*) def_sequence->elems->pdata;
258 			*count = (unsigned int) def_sequence->length->value._unsigned;
259 			goto end;
260 		} else {
261 			goto error;
262 		}
263 		break;
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 
bt_ctf_event_get_context(const struct bt_ctf_event * ctf_event)278 struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event)
279 {
280 	struct bt_context *ret = NULL;
281 	const struct ctf_file_stream *cfs;
282 	const struct ctf_trace *trace;
283 	const struct ctf_event_definition *event;
284 
285 	if (!ctf_event)
286 		return NULL;
287 
288 	event = ctf_event->parent;
289 	cfs = container_of(event->stream, const struct ctf_file_stream,
290 			parent);
291 	trace = cfs->parent.stream_class->trace;
292 	if (trace->parent.ctx)
293 		ret = trace->parent.ctx;
294 
295 	return ret;
296 }
297 
bt_ctf_event_get_handle_id(const struct bt_ctf_event * ctf_event)298 int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event)
299 {
300 	int ret = -1;
301 	const struct ctf_file_stream *cfs;
302 	const struct ctf_trace *trace;
303 	const struct ctf_event_definition *event;
304 
305 	if (!ctf_event)
306 		return -EINVAL;
307 
308 	event = ctf_event->parent;
309 	cfs = container_of(event->stream, const struct ctf_file_stream,
310 			parent);
311 	trace = cfs->parent.stream_class->trace;
312 	if (trace->parent.handle)
313 		ret = trace->parent.handle->id;
314 
315 	return ret;
316 }
317 
bt_ctf_get_timestamp(const struct bt_ctf_event * ctf_event)318 uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event)
319 {
320 	const struct ctf_event_definition *event;
321 
322 	if (!ctf_event)
323 		return -1ULL;
324 
325 	event = ctf_event->parent;
326 	if (event && event->stream->has_timestamp)
327 		return event->stream->real_timestamp;
328 	else
329 		return -1ULL;
330 }
331 
bt_ctf_get_cycles(const struct bt_ctf_event * ctf_event)332 uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event)
333 {
334 	const struct ctf_event_definition *event;
335 
336 	if (!ctf_event)
337 		return -1ULL;
338 
339 	event = ctf_event->parent;
340 	if (event && event->stream->has_timestamp)
341 		return event->stream->cycles_timestamp;
342 	else
343 		return -1ULL;
344 }
345 
bt_ctf_field_set_error(int error)346 static void bt_ctf_field_set_error(int error)
347 {
348 	bt_ctf_last_field_error = error;
349 }
350 
bt_ctf_field_get_error(void)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 
360 static const struct declaration_integer *
get_declaration_integer(const struct bt_declaration * decl)361 get_declaration_integer(const struct bt_declaration *decl)
362 {
363 	if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_INTEGER)
364 		return NULL;
365 	return container_of(decl, const struct declaration_integer, p);
366 }
367 
368 static const struct declaration_string *
get_declaration_string(const struct bt_declaration * decl)369 get_declaration_string(const struct bt_declaration *decl)
370 {
371 	if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_STRING)
372 		return NULL;
373 	return container_of(decl, const struct declaration_string, p);
374 }
375 
376 static const struct declaration_array *
get_declaration_array(const struct bt_declaration * decl)377 get_declaration_array(const struct bt_declaration *decl)
378 {
379 	if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_ARRAY)
380 		return NULL;
381 	return container_of(decl, const struct declaration_array, p);
382 }
383 
384 static const struct declaration_sequence *
get_declaration_sequence(const struct bt_declaration * decl)385 get_declaration_sequence(const struct bt_declaration *decl)
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 
bt_ctf_get_int_signedness(const struct bt_declaration * decl)392 int bt_ctf_get_int_signedness(const struct bt_declaration *decl)
393 {
394 	const struct declaration_integer *integer;
395 
396 	integer = get_declaration_integer(decl);
397 	if (!integer) {
398 		bt_ctf_field_set_error(-EINVAL);
399 		return -EINVAL;
400 	}
401 	return integer->signedness;
402 }
403 
bt_ctf_get_int_base(const struct bt_declaration * decl)404 int bt_ctf_get_int_base(const struct bt_declaration *decl)
405 {
406 	const struct declaration_integer *integer;
407 
408 	integer = get_declaration_integer(decl);
409 	if (!integer) {
410 		bt_ctf_field_set_error(-EINVAL);
411 		return -EINVAL;
412 	}
413 	return integer->base;
414 }
415 
bt_ctf_get_int_byte_order(const struct bt_declaration * decl)416 int bt_ctf_get_int_byte_order(const struct bt_declaration *decl)
417 {
418 	const struct declaration_integer *integer;
419 
420 	integer = get_declaration_integer(decl);
421 	if (!integer) {
422 		bt_ctf_field_set_error(-EINVAL);
423 		return -EINVAL;
424 	}
425 	return integer->byte_order;
426 }
427 
bt_ctf_get_int_len(const struct bt_declaration * decl)428 ssize_t bt_ctf_get_int_len(const struct bt_declaration *decl)
429 {
430 	const struct declaration_integer *integer;
431 
432 	integer = get_declaration_integer(decl);
433 	if (!integer) {
434 		bt_ctf_field_set_error(-EINVAL);
435 		return -EINVAL;
436 	}
437 	return (ssize_t) integer->len;
438 }
439 
bt_ctf_get_enum_int(const struct bt_definition * field)440 const struct bt_definition *bt_ctf_get_enum_int(const struct bt_definition *field)
441 {
442 	const struct definition_enum *def_enum;
443 
444 	if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) {
445 		bt_ctf_field_set_error(-EINVAL);
446 		return NULL;
447 	}
448 	def_enum = container_of(field, const struct definition_enum, p);
449 	return &def_enum->integer->p;
450 }
451 
bt_ctf_get_enum_str(const struct bt_definition * field)452 const char *bt_ctf_get_enum_str(const struct bt_definition *field)
453 {
454 	const struct definition_enum *def_enum;
455 	const struct declaration_enum *decl_enum;
456 	GArray *array;
457 	const char *ret;
458 
459 	if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) {
460 		bt_ctf_field_set_error(-EINVAL);
461 		return NULL;
462 	}
463 	def_enum = container_of(field, const struct definition_enum, p);
464 	decl_enum = def_enum->declaration;
465 	if (bt_get_int_signedness(&def_enum->integer->p)) {
466 		array = bt_enum_int_to_quark_set(decl_enum,
467 			bt_get_signed_int(&def_enum->integer->p));
468 	} else {
469 		array = bt_enum_uint_to_quark_set(decl_enum,
470 			bt_get_unsigned_int(&def_enum->integer->p));
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 
bt_ctf_get_encoding(const struct bt_declaration * decl)488 enum ctf_string_encoding bt_ctf_get_encoding(const struct bt_declaration *decl)
489 {
490 	enum ctf_string_encoding ret = 0;
491 	enum ctf_type_id type;
492 	const struct declaration_integer *integer;
493 	const struct declaration_string *string;
494 	const struct declaration_array *array;
495 	const struct declaration_sequence *sequence;
496 
497 	if (!decl)
498 		goto error;
499 
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)
506 			goto error;
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:
522 		string = get_declaration_string(decl);
523 		if (!string)
524 			goto error;
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:
534 		goto error;
535 	}
536 	return ret;
537 
538 error:
539 	bt_ctf_field_set_error(-EINVAL);
540 	return -1;
541 }
542 
bt_ctf_get_array_len(const struct bt_declaration * decl)543 int bt_ctf_get_array_len(const struct bt_declaration *decl)
544 {
545 	const struct declaration_array *array;
546 
547 	array = get_declaration_array(decl);
548 	if (!array)
549 		goto error;
550 	return array->len;
551 
552 error:
553 	bt_ctf_field_set_error(-EINVAL);
554 	return -1;
555 }
556 
bt_ctf_get_uint64(const struct bt_definition * field)557 uint64_t bt_ctf_get_uint64(const struct bt_definition *field)
558 {
559 	uint64_t ret = 0;
560 
561 	if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER)
562 		ret = bt_get_unsigned_int(field);
563 	else
564 		bt_ctf_field_set_error(-EINVAL);
565 
566 	return ret;
567 }
568 
bt_ctf_get_int64(const struct bt_definition * field)569 int64_t bt_ctf_get_int64(const struct bt_definition *field)
570 {
571 	int64_t ret = 0;
572 
573 	if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER)
574 		ret = bt_get_signed_int(field);
575 	else
576 		bt_ctf_field_set_error(-EINVAL);
577 
578 	return ret;
579 }
580 
bt_ctf_get_char_array(const struct bt_definition * field)581 char *bt_ctf_get_char_array(const struct bt_definition *field)
582 {
583 	char *ret = NULL;
584 	GString *char_array;
585 
586 	if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) {
587 		char_array = bt_get_char_array(field);
588 		if (char_array) {
589 			ret = char_array->str;
590 			goto end;
591 		}
592 	}
593 	bt_ctf_field_set_error(-EINVAL);
594 
595 end:
596 	return ret;
597 }
598 
bt_ctf_get_string(const struct bt_definition * field)599 char *bt_ctf_get_string(const struct bt_definition *field)
600 {
601 	char *ret = NULL;
602 
603 	if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING)
604 		ret = bt_get_string(field);
605 	else
606 		bt_ctf_field_set_error(-EINVAL);
607 
608 	return ret;
609 }
610 
bt_ctf_get_float(const struct bt_definition * field)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 
bt_ctf_get_variant(const struct bt_definition * field)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 }
640 
bt_ctf_get_struct_field_count(const struct bt_definition * field)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);
652 	} else {
653 		bt_ctf_field_set_error(-EINVAL);
654 	}
655 
656 	return ret;
657 }
658 
bt_ctf_get_struct_field_index(const struct bt_definition * field,uint64_t i)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 
bt_ctf_get_event_decl_list(int handle_id,struct bt_context * ctx,struct bt_ctf_event_decl * const ** list,unsigned int * count)680 int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx,
681 		struct bt_ctf_event_decl * const **list,
682 		unsigned int *count)
683 {
684 	struct bt_trace_handle *handle;
685 	struct bt_trace_descriptor *td;
686 	struct ctf_trace *tin;
687 
688 	if (!ctx || !list || !count)
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 
699 	*list = (struct bt_ctf_event_decl * const*) tin->event_declarations->pdata;
700 	*count = tin->event_declarations->len;
701 	return 0;
702 
703 error:
704 	return -1;
705 }
706 
bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl * event)707 const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event)
708 {
709 	if (!event)
710 		return NULL;
711 
712 	return g_quark_to_string(event->parent.name);
713 }
714 
bt_ctf_get_decl_fields(struct bt_ctf_event_decl * event_decl,enum bt_ctf_scope scope,struct bt_ctf_field_decl const * const ** list,unsigned int * count)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;
725 
726 	if (!event_decl || !list || !count)
727 		return -EINVAL;
728 
729 	*count = 0;
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 
bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl * field)831 const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field)
832 {
833 	if (!field)
834 		return NULL;
835 
836 	return rem_(g_quark_to_string(((struct declaration_field *) field)->name));
837 }
838 
bt_ctf_get_decl_from_def(const struct bt_definition * def)839 const struct bt_declaration *bt_ctf_get_decl_from_def(const struct bt_definition *def)
840 {
841 	if (def)
842 		return def->declaration;
843 
844 	return NULL;
845 }
846 
bt_ctf_get_decl_from_field_decl(const struct bt_ctf_field_decl * field)847 const struct bt_declaration *bt_ctf_get_decl_from_field_decl(
848 		const struct bt_ctf_field_decl *field)
849 {
850 	if (field)
851 		return ((struct declaration_field *) field)->declaration;
852 
853 	return NULL;
854 }
855