4 * Linux Trace Toolkit Control Library
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
16 #include <common/error.hpp>
17 #include <common/macros.hpp>
18 #include <lttng/event-field-value-internal.hpp>
21 struct lttng_event_field_value
*create_empty_field_val(
22 enum lttng_event_field_value_type type
, size_t size
)
24 struct lttng_event_field_value
*field_val
;
26 field_val
= zmalloc
<lttng_event_field_value
>(size
);
31 field_val
->type
= type
;
37 struct lttng_event_field_value
*lttng_event_field_value_uint_create(
40 struct lttng_event_field_value_uint
*field_val
;
42 field_val
= lttng::utils::container_of(create_empty_field_val(
43 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
,
45 <tng_event_field_value_uint::parent
);
54 lttng_event_field_value_destroy(&field_val
->parent
);
57 return &field_val
->parent
;
60 struct lttng_event_field_value
*lttng_event_field_value_int_create(
63 struct lttng_event_field_value_int
*field_val
;
65 field_val
= lttng::utils::container_of(create_empty_field_val(
66 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
,
68 <tng_event_field_value_int::parent
);
77 lttng_event_field_value_destroy(&field_val
->parent
);
80 return &field_val
->parent
;
84 struct lttng_event_field_value_enum
*create_enum_field_val(
85 enum lttng_event_field_value_type type
, size_t size
)
87 struct lttng_event_field_value_enum
*field_val
;
89 field_val
= lttng::utils::container_of(create_empty_field_val(type
, size
),
90 <tng_event_field_value_enum::parent
);
95 lttng_dynamic_pointer_array_init(&field_val
->labels
, free
);
99 lttng_event_field_value_destroy(&field_val
->parent
);
105 struct lttng_event_field_value
*lttng_event_field_value_enum_uint_create(
108 struct lttng_event_field_value_enum_uint
*field_val
;
110 field_val
= lttng::utils::container_of(create_enum_field_val(
111 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
,
113 <tng_event_field_value_enum_uint::parent
);
118 field_val
->val
= val
;
122 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
125 return &field_val
->parent
.parent
;
128 struct lttng_event_field_value
*lttng_event_field_value_enum_int_create(
131 struct lttng_event_field_value_enum_int
*field_val
;
133 field_val
= lttng::utils::container_of(create_enum_field_val(
134 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
,
136 <tng_event_field_value_enum_int::parent
);
141 field_val
->val
= val
;
145 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
148 return &field_val
->parent
.parent
;
151 struct lttng_event_field_value
*lttng_event_field_value_real_create(double val
)
153 struct lttng_event_field_value_real
*field_val
= lttng::utils::container_of(
154 create_empty_field_val(
155 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
,
157 <tng_event_field_value_real::parent
);
163 field_val
->val
= val
;
167 lttng_event_field_value_destroy(&field_val
->parent
);
170 return &field_val
->parent
;
173 struct lttng_event_field_value
*lttng_event_field_value_string_create_with_size(
174 const char *val
, size_t size
)
176 struct lttng_event_field_value_string
*field_val
= lttng::utils::container_of(
177 create_empty_field_val(
178 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
,
180 <tng_event_field_value_string::parent
);
187 field_val
->val
= strndup(val
, size
);
188 if (!field_val
->val
) {
195 lttng_event_field_value_destroy(&field_val
->parent
);
198 return &field_val
->parent
;
201 struct lttng_event_field_value
*lttng_event_field_value_string_create(
205 return lttng_event_field_value_string_create_with_size(val
,
210 void destroy_field_val(void *field_val
)
212 lttng_event_field_value_destroy((lttng_event_field_value
*) field_val
);
215 struct lttng_event_field_value
*lttng_event_field_value_array_create(void)
217 struct lttng_event_field_value_array
*field_val
= lttng::utils::container_of(
218 create_empty_field_val(
219 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
,
221 <tng_event_field_value_array::parent
);
227 lttng_dynamic_pointer_array_init(&field_val
->elems
, destroy_field_val
);
231 lttng_event_field_value_destroy(&field_val
->parent
);
234 return &field_val
->parent
;
237 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
243 switch (field_val
->type
) {
244 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
245 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
247 struct lttng_event_field_value_enum
*enum_field_val
=
248 lttng::utils::container_of(field_val
,
249 <tng_event_field_value_enum::parent
);
251 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
254 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
256 struct lttng_event_field_value_string
*str_field_val
=
257 lttng::utils::container_of(field_val
,
258 <tng_event_field_value_string::parent
);
260 free(str_field_val
->val
);
263 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
265 struct lttng_event_field_value_array
*array_field_expr
=
266 lttng::utils::container_of(field_val
,
267 <tng_event_field_value_array::parent
);
269 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
282 int lttng_event_field_value_enum_append_label_with_size(
283 struct lttng_event_field_value
*field_val
,
284 const char *label
, size_t size
)
289 LTTNG_ASSERT(field_val
);
291 new_label
= strndup(label
, size
);
297 ret
= lttng_dynamic_pointer_array_add_pointer(
298 <tng::utils::container_of(field_val
,
299 <tng_event_field_value_enum::parent
)->labels
,
310 int lttng_event_field_value_enum_append_label(
311 struct lttng_event_field_value
*field_val
,
315 return lttng_event_field_value_enum_append_label_with_size(field_val
,
316 label
, strlen(label
));
319 int lttng_event_field_value_array_append(
320 struct lttng_event_field_value
*array_field_val
,
321 struct lttng_event_field_value
*field_val
)
323 LTTNG_ASSERT(array_field_val
);
324 LTTNG_ASSERT(field_val
);
325 return lttng_dynamic_pointer_array_add_pointer(
326 <tng::utils::container_of(array_field_val
,
327 <tng_event_field_value_array::parent
)->elems
,
331 int lttng_event_field_value_array_append_unavailable(
332 struct lttng_event_field_value
*array_field_val
)
334 LTTNG_ASSERT(array_field_val
);
335 return lttng_dynamic_pointer_array_add_pointer(
336 <tng::utils::container_of(array_field_val
,
337 <tng_event_field_value_array::parent
)->elems
,
341 enum lttng_event_field_value_type
lttng_event_field_value_get_type(
342 const struct lttng_event_field_value
*field_val
)
344 enum lttng_event_field_value_type type
;
347 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
351 type
= field_val
->type
;
357 enum lttng_event_field_value_status
358 lttng_event_field_value_unsigned_int_get_value(
359 const struct lttng_event_field_value
*field_val
, uint64_t *val
)
361 enum lttng_event_field_value_status status
;
363 if (!field_val
|| !val
) {
364 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
368 switch (field_val
->type
) {
369 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
370 *val
= lttng::utils::container_of(field_val
,
371 <tng_event_field_value_uint::parent
)->val
;
373 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
375 const struct lttng_event_field_value_enum
*field_val_enum
=
376 lttng::utils::container_of(
377 field_val
, <tng_event_field_value_enum::parent
);
378 const struct lttng_event_field_value_enum_uint
*field_val_enum_uint
=
379 lttng::utils::container_of(field_val_enum
,
380 <tng_event_field_value_enum_uint::parent
);
381 *val
= field_val_enum_uint
->val
;
385 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
389 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
395 enum lttng_event_field_value_status
396 lttng_event_field_value_signed_int_get_value(
397 const struct lttng_event_field_value
*field_val
, int64_t *val
)
399 enum lttng_event_field_value_status status
;
401 if (!field_val
|| !val
) {
402 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
406 switch (field_val
->type
) {
407 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
408 *val
= lttng::utils::container_of(field_val
,
409 <tng_event_field_value_int::parent
)->val
;
411 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
413 const struct lttng_event_field_value_enum
*field_val_enum
= lttng::utils::container_of(
415 <tng_event_field_value_enum::parent
);
416 const struct lttng_event_field_value_enum_int
*field_val_enum_uint
=
417 lttng::utils::container_of(field_val_enum
,
418 <tng_event_field_value_enum_int::parent
);
419 *val
= field_val_enum_uint
->val
;
423 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
427 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
433 enum lttng_event_field_value_status
434 lttng_event_field_value_real_get_value(
435 const struct lttng_event_field_value
*field_val
, double *val
)
437 enum lttng_event_field_value_status status
;
439 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
441 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
445 *val
= lttng::utils::container_of(field_val
,
446 <tng_event_field_value_real::parent
)->val
;
447 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
454 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
456 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
457 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
460 enum lttng_event_field_value_status
461 lttng_event_field_value_enum_get_label_count(
462 const struct lttng_event_field_value
*field_val
,
465 enum lttng_event_field_value_status status
;
467 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
468 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
472 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
473 <tng::utils::container_of(field_val
,
474 <tng_event_field_value_enum::parent
)->labels
);
475 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
481 const char *lttng_event_field_value_enum_get_label_at_index(
482 const struct lttng_event_field_value
*field_val
,
486 const struct lttng_event_field_value_enum
*enum_field_val
;
488 if (!field_val
|| !is_enum_field_val(field_val
)) {
493 enum_field_val
= lttng::utils::container_of(field_val
,
494 <tng_event_field_value_enum::parent
);
496 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
501 ret
= (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
508 enum lttng_event_field_value_status
lttng_event_field_value_string_get_value(
509 const struct lttng_event_field_value
*field_val
,
512 enum lttng_event_field_value_status status
;
514 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
515 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
519 *value
= lttng::utils::container_of(field_val
,
520 <tng_event_field_value_string::parent
)->val
;
521 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
527 enum lttng_event_field_value_status
lttng_event_field_value_array_get_length(
528 const struct lttng_event_field_value
*field_val
,
529 unsigned int *length
)
531 enum lttng_event_field_value_status status
;
533 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
535 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
539 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
540 <tng::utils::container_of(field_val
,
541 <tng_event_field_value_array::parent
)->elems
);
542 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
548 enum lttng_event_field_value_status
549 lttng_event_field_value_array_get_element_at_index(
550 const struct lttng_event_field_value
*field_val
,
552 const struct lttng_event_field_value
**elem_field_val
)
554 enum lttng_event_field_value_status status
;
555 const struct lttng_event_field_value_array
*array_field_val
;
557 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
559 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
563 array_field_val
= lttng::utils::container_of(
564 field_val
, <tng_event_field_value_array::parent
);
566 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
567 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
571 *elem_field_val
= (lttng_event_field_value
*) lttng_dynamic_pointer_array_get_pointer(
572 &array_field_val
->elems
, index
);
573 if (*elem_field_val
) {
574 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
576 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;